CRYPTU.IO
FARTY.logo
lottery.php
Responsive image


Find information and answers to your questions at CRYPTU.IO's Help Desk


Index


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 cryptocurrency, 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)


 

 

Cryptu Promotion Ecosystem (CryptuProEco®) is an unique, professional and comprehensive cryptocurrency-based promotion management ecosystem under Cryptu.io without any other example in the crypto world that you may enter it to increase your revenue. In other word for 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.

 

The CryptuProEco® consists of two sections, Promoters and Providers. In other word if you have your own business, and you want to promote your business, you may register a new Service as a Provider else you may would like to register as a new Promoter on a previously registered Service by a Provider to take benefit of your promotions.

 

Promoter

 

A person with a wallet address that wants to be a Promoter in CryptuProEco® and try to reach investors. 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 Promoter(s). He/she/it creates a Service on the CryptuProEco® to starts his/her/its promotion ecosystem.

 

Service

 

In a word, a Service is a business. The owner of a company or a person (Provider) may like to extend his/her/its business. You can register your goods/services/business as a Service on the CryptuProEco® and Promoter(s) can promote/advertise and sell your articles, helping your business to be developed more. They can help you to absorb the customers, so your revenue will increase. Also, the Promoter(s) get a commission of your sale according their activity.

 

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 Ecosystem (CryptuProEco®) emphasizes 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!


Cryptu Promotion Ecosystem Contract


 

 

CryptuProEco® Contract (CryptuPromotionManager V1)

 

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


Contract info

 

Contract name: CryptuPromotionManager

 

Contract address: 0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c

 

View CryptuPromotionManager.sol on BscScan.

 

View the CryptuProEco® White Paper for more information.


CryptuProEco® Structure

 

The CryptuProEco®, which is invented by Cruptu.io is a novel cryptocurrency-based promotion management ecosystem, 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. CryptuProEco® structure is shown in Fig. 1.

 

Fig. 1: CryptuProEco® 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 CryptuProEco®. The Promoter level is the lowest (4) now. If he/she gives his/her 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 CryptuProEco® 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 CryptuProEco® 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 Commission and Cluster Commission 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 CryptuProEco®'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 CryptuPromotionManager 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 CryptuProEco® otherwise it reverts.
Consumer address Address of the Consumer contract, which will use the CryptuProEco®. Consumer contract must be a verified contract, so the CryptuProEco®'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!
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 CryptuProEco®. Consumer contract must be a verified contract, so the CryptuProEco®'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!
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 CryptuProEco®, that a successful buy operation is finished. It emits OnCodeUsed event.

 

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

 

Consumer contract must be a verified contract, so the CryptuProEco®'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 CryptuPromotionManager 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/services.
commissionAmount uint256 Transferred amount of Promoter's commission.
fee uint256 Transferred amount of CryptuProEco® 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 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 CryptuPromotionManager 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 CryptuPromotionManager 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 CryptuProEco®’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


 

 

In this instruction, you can learn how the CryptuProEco® works and how to use it.

 

The CryptuProEco® webpage consists of three main sections, Tops, Promoters and Providers. In other word if you have your own business, and you want to promote your business, you may register a new Service as a Provider else you may would like to register as a new Promoter on a previously registered Service by a Provider to take benefit of your promotions.

 

The first step is to connect your wallet (Fig. 1). Our registration is free of charge for the Promoter(s).

 

Fig. 1: Connecting Wallet.

 

You may see a column in the left-hand side of the CryptoProEco® webpage contains three main sections. The first item is “Tops“, the second is “Promoters“ and the third one is “Providers“ (Fig. 2).

 

Fig. 2: Main Sections.

 

The “Tops“ has two sub-items (lists):

 

• Top Services (Providers)

• Top Promoters

 

Top Services

 

The top Services may be seen in Fig. 3. This list shows the top businesses which are registered in the CryptuProEco® and they are sorted based on their sale counts.

 

Fig. 3: Top Services.

 

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

 

Column Title Description
Name The name (or title) of the Service.
Rank The rank of the desired Service may be shown in the rank place based on total sale count.
Sale Count The amount of the companies’ articles that are traded on CryptuProEco®.
Total Income ($) The revenue of all Promoters of the top Services in US Dollar (if the crypto-currency price is retrievable) till now.
Total Income (Crypto) The revenue of all Promoters of the top Services in cryptocurrency, by the currency in which the Service uses. The currency is set during the Service registration (refer sec. 5-11).
Promoters Count Number of the Promoters that are registered in the desired top Services.
Currency The acceptable currency of the desired top Services (token/native cryptocurrency).
Website The website of the Service.

 

Top Promoters

 

In this section, the top Promoters of the total ecosystems is shown as Fig. 4. The list shows the top Promoters’ situation based on their sale averages in the CryptuProEco®

 

Fig. 4: Top Promoters.

 

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

 

Column Title Description
Nickname This is the title that each Promoter has chosen for him/herself during registration.
Level The level of each Promoter is specified by his/her activity (refer to the CryptuProEco® Contract).
Sale Average The average of the sold articles by the Promoter per time, for example this average can be daily or any time slice in the order of seconds, specified by the related Service Provider.
Sale Count The amount of the articles that is sold by each Promoter.
Income ($) The income of each Promoter in US Dollar (if the cryptocurrency price is retrievable).
Income (Crypto) The income of each Promoter in cryptocurrency.
Commission (%) Total percentage of earned by the Promoter.

 

The “Promoters“ has two sub-items:

 

• Register New Promoter

• Your Promotions

 

Register New Promoter

 

A Promoter can register him/herself using a wallet (just MetaMask is supported now) that must be connected to the CryptuProEco®.

 

There are two ways to register as Promoter:

 

• Registration with a Referral Code; In this way, you may have a Referral Code of another Promoter and you want to be registered as his/her sub-Promoter.

• Registration without a Referral Code; In this option, you don't have any Referral Code, so you would create your own Cluster in the selected Service.

 

Each Promoter should have been registered and their information must enter in the "Register New Promoter" 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 desired Service is selected here. If you don’t have a Referral Code, obtained from other Promoters, you have to choose a Service, so you would create a new Cluster in the selected Service and you become its owner, else and if other Promoter has introduced a Service, so you will have a Referral Code, so you have to select “By Referral Code” and enter it in the ”Referral” field. So, you will become the sub-Promoter of that Promoter, whom you entered his/her Referral Code automatically. (refer to the CryptuProEco® Contract).
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® Contract).
Nickname A unique nickname in a Service, that you choose for yourself in the selected Service. You will be known by this nickname.
Email Your email should be written here. It is better to fill it in order to be used by other Promoters of the Cluster to make contact by each others.

 

You should click “Submit” after completing all fields. Then you are A NEW PROMOTER in a Cluster (refer to the CryptuProEco® Contract).

 

Your Promotions

 

Your promotions information can be shown in the “Your Promotions” section as Fig. 6 till Fig. 12.

 

Fig. 6: Your Promotions-Part 1.

 

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

 

Column Title Description
Nickname Your nickname that has been chosen at registration time, is shown here.
Referral Your Referral Code that is unique over the entire CryptuProEco®. You may give it to other Promoters that they can become your sub-Promoters or to a Buyer, whom may use it to buy articles with discount. (Refer to the CryptuProEco® Contract)
Email Your registered email address.
Joined The date of your registration.
Balance It is the current income balance. If some articles are sold using your Referral Code, you will see commission balance here.
Service The Service(s) that you are registered in as Promoter. By selecting a Service, you can see your promotion activity and information.
Withdraw You can withdraw your balance by pressing this button.

 

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:

 

• Total Clusters:

Here is the information of all Clusters of the selected Service. This list is changed by selecting the various Services.

- Count:

Number of Clusters which is formed in the selected Service.

- Sale:

Number of the total sales of the selected Service (by the total Clusters).

- Average:

Sale average of the total sold articles of the selected Service per time, for example this average can be daily or any time slice in the order of seconds, specified by the Service Provider

- Income (Crypto):

Total income of the selected Service in cryptocurrency. In this example, it is TFARTY.

- Income ($):

Total income of the selected Service in US Dollar (if retrievable).

- Sale Share Chart:

Your sale compare to total Clusters of the Service, ratio in percent.

 

• Your Cluster:

Here is the information of the Cluster that you are registered in as a Promoter.

- Owner:

It is the nickname of your Cluster owner.

- Promoters:

Number of Promoters of your Cluster (refer to the CryptuProEco® Contract)

- Sale:

Number of products that your Cluster has sold till now.

- Average:

Sale average of the sold articles (in the selected Service) by the all Promoters of your Cluster per time, for example this average can be daily or any time slice in the order of seconds.

- Income (Crypto):

Your Cluster total income in cryptocurrency for the selected Service. In this example, it is TFARTY.

- Income ($):

Your Cluster income in US Dollar.

- Sale Share Chart:

Your sale compare to other Promoters of the Cluster, ratio in percent.

 

• Your Promotions:

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

- Sale:

Amount of the articles that are sold using your Referral Code.

- Average:

Sale average of the articles that are sold using your Referral Code over time.

- Income (Crypto):

Your own total income in cryptocurrency from the beginning. In this example, it is TFARTY.

- Income ($):

Your own income in US Dollar from the beginning.

- Direct Commission:

The percentage of your sale Direct Commission.

- Cluster Commission:

The percentage of your sale Cluster Commission.

- Total Commission:

It is the Total Commission, sum of direct and cluster commissions.

 

• Your Cluster's Diagram:

The Cluster structure that you are registered in. You can see all of Promoters in your Cluster of the selected Service in a tree chart view, may be shown as Fig. 8.

 

Fig. 8: Your Promotions-Part 3.

 

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 (refer to the CryptuProEco® Contract).

 

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, Rank of your Cluster, sale count, Sale Average and number of the Promoters may be seen simultaneously. By clicking the legend boxes, you can turn the traces on/off.

 

• Your History:

Here is your promotion 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, your own Direct Commission, number of articles that you have sold by your promotion and the Sale Average are shown in this graph.

 

• Contact:

Contacts' information of your Cluster as their Nicknames and Emails are shown in the Fig. 12. You can also export it as an excel data.

 

Fig. 12: Your Promotions-Part 7.

 

Register New Service

 

Here, You can register your business as a Service in the Provider role. 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 Name of your Service.
Consumer Address of your Consumer smart contract, which is deployed before. This contract must be verified on the block explorer, in order to be audit-able by third parties. Please refer to How to Implement Promotion Manager in My Consumer Contract for more information.
Cluster Share You can define the score of the Cluster in percent. In other word, according to the 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. You can set the Cluster Share (or Cluster Score) here. By pressing the “Defaults” button, a predefined setting can be loaded to this field. Data format must be like the below text:

[["2000","0","100"],["4000","100","200"],["6000","200","300"],["8000","300","400"],["10000","400","1000000"]]

It is a 5-elements array of ClusterBreak structers (refer to the CryptuProEco® Contract).
Level Share Each cluster has 4 levels that each level has its own share (or its own percentage). By pressing the “Defaults” button, a predefined setting can be loaded to this field. Data format must be like the below text:

[4000,3000,2000,1000]

(refer to the CryptuProEco® Contract).
Z1 (%) Direct Commission Weight Factor in percent. By pressing the “Defaults” button, a predefined setting can be loaded to this field.
Z2 (%) Cluster Commission Weight Factor in percent. By pressing the “Defaults” button, a predefined setting can be loaded to this field.
Min Discount (%) It is the minimum discount that a Buyer can take benefit of it, if he/she uses a Referral Code. By pressing the “Defaults” button, a predefined setting can be loaded to this field.
Max Discount (%) It is the maximum discount that a Buyer can take benefit of it, if he/she uses a Referral Code. It is the Service maximum discount limit. By pressing the “Defaults” button, a predefined setting can be loaded to this field.
Averaging Period (in second) Number that defines the averaging period for the Promoters over time, which must be specified in seconds (please refer to the item 2-3). By pressing the “Defaults” button, a predefined setting can be loaded to this field.
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. By pressing the “Defaults” button, a predefined setting can be loaded to this field.
Currency Here is the contract address of acceptable cryptocurrency which the Consumer contract uses to sell articles. It can be any token address or 0x0000000000000000000000000000000000000000 (for specifying native coin, Ex: BNB).
Fee Payment Service registration, has cost which must be paid by a Service Provider to the CryptuProEco®. At the registration time you can specify the way that you pay this fee as one of the following ways:

A) Cash
By choosing the cash method, you have to pay the specified fee in BNB, during the registration transaction.

B) Sale Percentage
Upon selecting Sale Percentage option, You don't pay any fee at the registration time, just you pay it in form of your Service cryptocurrency, when an article is sold by a Promoter (refer to How to Implement Promotion Manager in My Consumer Contract for more information).
Defaults You may change the values to their default via this button.
Submit You should finalize your registration after filling all fields. So please click the “Submit” button when you are sure that you have filled all fields. After confirmation of the registration transaction, a message informs it.

“Service registered successfully!”

 

Your Provided Services

 

You can see, your registered Services here, 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 your registered Services here.
Cluster You can choose each Cluster of the selected Service.
Promoter Each Promoter with their IDs is shown here. You can choose each Promoter of the selected Service to view his/her activity.

 

Service Parameters:

As shown in Fig. 15, parameters of the selected Service can be changed here if it is needed.

 

Fig. 15: Service Parameters.

 

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

 

field Title Description
Consumer Address of your Consumer smart contract, which is deployed before. This contract must be verified on the block explorer, in order to be audit-able by third parties. Please refer to How to Implement Promotion Manager in My Consumer Contract for more information.
Cluster Share You can define the score of the Cluster in percent. In other word, according to the 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. You can set the Cluster Share (or Cluster Score) here. By pressing the “Defaults” button, a predefined setting can be loaded to this field. Data format must be like the below text:

[["2000","0","100"],["4000","100","200"],["6000","200","300"],["8000","300","400"],["10000","400","1000000"]]

It is a 5-elements array of ClusterBreak structers (refer to the CryptuProEco® Contract).
Level Share Each cluster has 4 levels that each level has its own share (or its own percentage). By pressing the “Defaults” button, a predefined setting can be loaded to this field. Data format must be like the below text:

[4000,3000,2000,1000]

(refer to the CryptuProEco® Contract).
Z1 (%) Direct Commission Weight Factor in percent. By pressing the “Defaults” button, a predefined setting can be loaded to this field.
Z2 (%) Cluster Commission Weight Factor in percent. By pressing the “Defaults” button, a predefined setting can be loaded to this field.
Min Discount (%) It is the minimum discount that a Buyer can take benefit of it, if he/she uses a Referral Code. By pressing the “Defaults” button, a predefined setting can be loaded to this field.
Max Discount (%) It is the maximum discount that a Buyer can take benefit of it, if he/she uses a Referral Code. It is the Service maximum discount limit. By pressing the “Defaults” button, a predefined setting can be loaded to this field.
Averaging Period (in second) Number that defines the averaging period for the Promoters over time, which must be specified in seconds (please refer to the item 2-3). By pressing the “Defaults” button, a predefined setting can be loaded to this field.
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. By pressing the “Defaults” button, a predefined setting can be loaded to this field.
Dex Router (Optional) DEX router contract address is used for getting cryptocurrency price.
Website Here you can add or change your business website.
Submit You can finish your work by pressing the “Submit” button. So, your change has been set.

 

• Selected Service, Selected Cluster and Selected Promoter Information:

As you select the desired Service, according to "Your Provided Services", summary of information of the Selected Service, Cluster and Promoter may be shown as Fig. 16 and Fig. 17.

 

Fig. 16: Information of the selected Service-part 1.

 

The Selected Service consist of fields as described in the following table:

 

field Title Description
ID Unique ID of the selected Service.
Name Name of the selected Service.
Total Promoters Number of the total Promoters of the Service.
Clusters Number of clusters of the Service.
Sale Number of total sales of the Service.
Average Sale average of the Service.
Income (Crypto) Total income of the Service in cryptocurrency. In this example, TFARTY.
Income ($) Total income of the Service in US Dollar (if price is retrievable).

 

The Selected Cluster consist of fields as described in the following table:

 

field Title Description
ID Unique ID of the selected Cluster.
Owner Nickname of the first Promoter who has formed the Cluster for the first time.
Promoters Number of total Promoters of the selected Cluster.
Sale Number of total sales of the selected Cluster.
Average Sale average of the selected Cluster.
Income (Crypto) Total income of the selected Cluster in cryptocurrency. In this example, TFARTY.
Income ($) Total income of the selected Cluster in US Dollar (if price is retrievable).

 

The Selected Promoter consist of fields as described in the following table:

 

field Title Description
ID Unique ID of the selected Promoter of the Service.
Nickname Nickname of the selected Promoter.
Sale Number of total sales of the selected Promoter.
Average Number of sale average of the selected Promoter.
Income (Crypto) Total income of the selected Promoter in cryptocurrency. In this example, TFARTY.
Income ($) Total income of the selected Promoter in US Dollar (if price is retrievable).
Direct Commission It is the selected Promoter commission in percent.
Cluster Commission Cluster Commission percentage of the selected Promoter.
Total Commission Sum of Direct Commission and Cluster Commission.
Referral Discount Calculated referral discount of the selected Promoter according to his/her activity. It is limited between min/max discount of the Service.
Contact This is the email of the selected Promoter.

 

As it is shown in Fig. 17, you may see the information of the Selected Service, Selected Cluster and Selected Promoter in the various graphs.

 

Fig. 17: Information of the selected Service-part 2.

 

Cluster Diagram:

The formed Cluster in the desired Service may be shown as Fig. 18. There may be several Clusters for each Service that you can check them all by selecting it in the drop down lists. As it is seen, the Cluster Owner Promoter is located at the top-most level. The others are in the lower levels.

 

Fig. 18: Cluster Diagram.

 

Service History:

Here is the overall Service history which may be shown in Fig. 19.

 

Fig. 19: Service History.

 

In this graph you can see the selected Service performance. Income, sale count, sale average and Promoters count may be shown in the current graph. The graphs may be changed by changing the selected Service.

 

Cluster History:

In this graph (Fig. 20), you may see the selected Cluster history information. These data contain the Rank, sale count, sale average and Promoters count of the selected Cluster, that may be seen simultaneously. The graphs may be changed by changing the selected Cluster.

 

Fig. 20: Cluster History.

 

Promoter History:

Each Promoter of the selected Service and the selected Cluster has his/her history that is shown in Fig. 21.

 

Fig. 21: Promoter History.

 

In the Fig. 21, Cluster Commission (%), Direct Commission (%), sale count and sale average of the selected Promoter is shown. By clicking the legend boxes, you can turn the traces on/off

 

Also, you can export the contact emails of the members of selected Cluster to an excel file and download it.

 

CryptuLotto® (Cryptu Lottery)


 

 

Cryptu Lottery (CryptuLotto®) is a secure and reliable lottery platform under Cryptu.io in which gives the players the chance to raise money and win huge $FARTY prizes by buying ticket(s). It's easy, fair, and you can enter as often as you like as long as you have the $FARTY to buy a ticket.

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

• Due to weekly lottery, there is one draw after 48 hours, so you should wait until the final winning number is declared by the platform.

 

Hint! A 5-day relaxation period is considered in the desired week after final winning number declaration.

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!

 

View the CryptuLotto® contract for mor information.

 

Specifications

 

• Cheaper ticket prices (~$2.49 USDT in $FARTY per ticket) that don't swing wildly with the price of $FARTY.

• Individual user Lottery entry limit: No overall limit, but only 100 tickets can be bought at a time.

• Paying for one ticket will give users a random 6-digit combination with each digit being between 0-9, for e.g. “5-8-3-6-2-1”. Match numbers from the left side to win prizes. 6-tiered prize pool brackets with increasing prize pools as more numbers are matched.

• Manual number selection (optional), so users can use their lucky numbers at buying ticket(s).

• Bulk ticket discounts.

• Lower overall fees.

 

Ticket Costs and Bulk Purchase Discount

 

The price of a ticket in $FARTY is approximately ~$2.49 USDT.

The bulk discount reward is for buying larger amounts of tickets. Buying multiple CryptuLotto® tickets at once gives a bulk discount on your purchase. If you're buying only 2 tickets, the discount is negligible, but will add up quickly as you increase the number of tickets to buy in one transaction. The discount only applies to each transaction up to 100 tickets. The discount does not carry over to the next transaction or next round.

 

How To Win

 

If the digits on your purchased ticket(s) match the winning numbers drawn at the end of a CryptuLotto® round in correct order (match numbers, from the left side of your ticket), you win a portion of the prize pool.

 

• Matching even just the first number will win you a small prize.

• Match more numbers to win a share of a larger prize pool.

 

Winning Criteria

 

The digits on your ticket should match in the correct order to win. You should match the numbers of your ticket digits with the winning number of the CryptuLotto® round, from the left side in back-to-back form. Matching more numbers means that you have won more portion of the prize pool.

 

Example:

Suppose that the drawn number is 987654 and you have two tickets with numbers 987454 and 087654.

 

Ticket 1 (987454):

The first 3 numbers of the ticket and the drawn number is matched, the 4th numbers are not matched and the last 2 numbers are matched again. So only the first 3 numbers are considered as matched numbers..

 

Ticket 2 (087654):

The first number of the ticket and the drawn number are not matched but the next 5 numbers are matched. So, the ticket will not win anything in spite of matching other 5 right numbers.

 

The winning situation may be seen as follows:

 

 

You will only share in prizes from the highest prize bracket you are eligible for. A ticket matching the first three numbers will only be eligible for prizes from the match-three bracket, and not for the match-one or match-two brackets.

Remember: The digits must match in correct order, starting from left to right in back-to-back form.

 

Prize Sharing Across Prize Brackets

 

After a round is drawn, and tickets with matching numbers are determined, the prizes are awarded. The amount won by each ticket will depend on how many other tickets won in the same prize bracket.

For example, if you have the only ticket that matched three numbers in order, and the predetermined share of the prize pool for your bracket was 3000 $FARTY, you'll receive the full 3000 $FARTY. If, however, you and two other people match three numbers in order, the 3000 $FARTY would be split between the three winning tickets, meaning you would receive 1000 $FARTY.

 

See the CryptuLotto® FAQ for a breakdown of prizes across each bracket.

Cryptu Lottery Contract


 

 

CryptuLotto® Contract (CryptuLottery V1)

 

Fork of PancakeSwap Lottery contract by using ChainLinkVRF2 V2 and 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 CryptuPromotionManager 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


 

 

In this instruction, you can learn how to play a lottery in the CryptuLotto® and how to use it.

 

Start Your Game

 

You can save lots of $FARTY by taking part in CryptuLotto® and you will experience fun and excitation. More lottery tickets are sold, so there will be larger prize pool. When a prize pool is not won, the next pool will be increased. In other word the longer it's been since someone has won the jackpot, the larger the Lottery prize pool will be. When a round is open, people can buy ticket(s). Each ticket sold increases the prize pool further. Here's how to check the current round's prize pool and remaining time.

As you enter the CryptuLotto® webpage, you will see the amount of money in the pool in $. Also, the remaining time to the drawn of ongoing round or its status will be shown (as Fig. 1).

 

Fig. 1: Prize Pool and Remaining Time to Drawn.

 

As time passes, the prize pool is increased by selling more tickets. When a lottery jackpot isn't won, the next round's prize pool will increase; the longer it's been since someone has won the jackpot, the larger the Lottery prize pool will be.

The discount starts at 2 tickets, and scales all the way to 100 tickets where you will save almost 5% on your purchase (4.95% Bulk Discount).

 

How to Buy Ticket(s)

 

You only need to have $FARTY for buying tickets. Each ticket costs 2.49 USDT. You can see the value of $FARTY in beginning of the game.

The first step to play lottery in the CryptuLotto® is to connect your wallet (as Fig. 2).

 

Fig. 2: Connecting Wallet.

 

The second step is to click the buy ticket button (as Fig. 3).

There is a time between rounds where purchasing tickets isn't possible. Just check back CryptuLotto® after the countdown is over and if that's the case.

 

Fig. 3: Buy Ticket Button.

 

Buy Tickets dialog box will be shown as Fig. 4 for you to buy the number(s) of the ticket(s).

 

Fig. 4: Buy Tickets Dialog Box.

 

The ticket(s) count(s) shall be entered into the "count" field and also you can have extra discount by enter Referral Code that you have received from the others into the related field.

 

The third step is to click the "Enable" button (as Fig. 4).

Now you need to confirm and allow permission to the CryptuLotto® to withdraw your tokens at the next purchase steps (as Fig. 5).

 

Fig. 5: Confirmation Dialog Box.

 

The forth step is to click “Select Tickets” button (as Fig. 6) After confirmation of permission to withdraw tokens.

 

Fig. 6: Select Tickets Button.

 

At fifth step, The cryptulotto® will generate random unique ticket(s) number(s) based on the count that you have entered. Now you can choose your ticket(s) number(s) by pressing “Randomized” Button to generate your numbers randomly again or you can choose and customize your ticket(s) number(s) by clicking each digit (as Fig. 7). Also, you'll get a warning if you create duplicate tickets with same number and it is impossible to have two or more tickets with a unique number at one purchase.

If the numbers are ok, you will click the “Buy” button as Fig. 7 or close Select Tickets dialog box if you change your mind.

 

Fig. 7: Select Tickets Dialog Box.

 

The last step is to confirm the buying ticket(s) transaction as Fig. 8 after click the “Buy“ button on the Select Tickets dialog box.

 

Fig. 8: Buy Ticket(s) Confirmation Dialog Box.

 

View and Claim Your Ticket(s) After Buying

 

You can view your ticket(s) after buying them before the round's winning number is drawn as Fig. 9. “Your History“ panel will showing all of your ticket(s) and their numbers. You need to click on each desired round.

 

Fig. 9: Your History Panel.

 

As you see, “Your History” panel consist of several columns as described in the following table:

 

Column Title Description
Round The CryptuLotto® round number that you have bought ticket(s).
Count The total ticket(s) of each round that you have bought.
Prize If you win in each round, you will see your desired prize in this column. The ongoing round do not have any prize so you will see ”N/A” for this round.
Status Each ticket(s) may have 4 statuses: ”Ongoing”, ”Not Winning”, ”Claimable” and ”Claimed”.

If the round is not over, your ticket(s) status will be “Ongoing”.

If you have not won anything, so you will not have any prizes and the status will be “Not Winning”.

If your ticket(s) numbers have matched, as the Winning Criteria, so the status will be “Claimable”.

If you win a round and after withdrawing the prizes, the status will change to ”Claimed”.

 

When the ongoing round has ended and the winning numbers are available, you can check your ticket(s) to see if you won. The “Ongoing” Status will be changed to “Claimable” or “Not Winning”. So, you can click on ”Claimable” Button to receive your prize if you won as Fig. 10.

 

Fig. 10: Claimable Button.

 

By confirm the received claimed prizes transaction as Fig. 11 after click the “Claimable“ button on the “Your History“ panel, you will receive your prize in your wallet.

 

Fig. 11: Receive Claimed Prizes Confirmation Dialog Box.

 

View CryptuLotto® All Rounds History

 

In “All History“ panel, you can see history of all CryptuLotto® rounds as Fig. 12.

 

 

By typing your desired round number in “Round Field” and pressing the Enter key or by using the navigator buttons that can be used to access the next, previous, first, and last rounds, you can see the winning numbers, total prize and total players of each CryptuLotto® round.

 

As you see, the bottom of “All History” panel consist of several columns as described in the following table:

 

Column Title Description
Total Winners The number(s) of ticket(s) won in selected round of The CryptuLotto®.
Match Winners The number(s) of ticket(s) that are matched with the “Winning Number” from 1 to 6 as the Winning Criteria .
Prize The total prize for all “Match Winners” in related bracket.
Each The prize of each “Match Winner” in USDT in related bracket.

 

Hopefully you will be one of the CryptuLotto® winners.

 

CryptuLotto® FAQ


 

 

What if there are no winners?

 

If $FARTY in the prize pool isn't won it doesn't go to waste! Unclaimed $FARTY rolls over to the next CryptuLotto® round.

 

My ticket matches several numbers but I can't claim a prize.

 

Tickets are only eligible for prizes if matching numbers from left to right. See the CryptuLotto® documentation for a thorough explanation.

 

What are the main characteristics of the CryptuLotto®?

 

CryptuLotto® distributes prizes more widely than other regular network lotteries. It gives each ticket a 1 in 10 chance to match the first number, which means more tickets will at least win prize. More numbers need to be matched sequentially to win more prize.

 

CryptuLotto® introduces:

 

• Cheaper ticket prices (~$2.49 USDT in $FARTY per ticket) that don't swing wildly with the price of $FARTY

• Bulk ticket discounts

• 6-tiered prize pool brackets with increasing prize pools as more numbers are matched

• Manual number selection (optional), so users can use their lucky numbers

• Chainlink’s implementation of VRF for true, secure randomness

• Lower overall fees

 

How are prizes broken down between brackets?

 

Each bracket's prize pool is a portion of the total $FARTY in each CryptuLotto® round.

 

Bracket (Numbers matched in order) $FARTY Allocation
First 1 Number 2.5%
First 2 Numbers 5%
First 3 Numbers 10%
First 4 Numbers 12.5%
First 5 Numbers 20%
First 6 Numbers 50%

 

Can I exchange my tickets back to $FARTY?

 

No, once purchased you will not be able to convert your ticket back to $FARTY.

 

If I win, do I need to manually claim the prize?

 

Yes, you will need to back to the CryptuLotto® page, connect your wallet and check status under “Your History“. If you have wined, a “Claimable“ link will be appeared.

 

 

When does the CryptuLotto® start and finish?

 

The CryptuLotto® starts in Monday 0 AM UTC and ends in Wednesday 0 AM UTC.

 

How often is the CryptuLotto® drawn?

 

The CryptuLotto® drawn is weekly and the draw occurs at the 0 AM UTC Wednesday of each week.

 

What transaction fee will I pay for buying tickets?

 

Each ticket purchase will have one transaction. Purchasing a single ticket in a CryptuLotto® will cost a normal amount of fee for a transaction.

However, buying more tickets in that purchase will increase the fee. Buying 100 tickets rather than 1 will not multiply the fee by 100, but may increase the fee amount by 5-6 times (though this varies).

 

How does the bulk discount work?

 

The bulk discount reward is for buying larger amounts of tickets. If you're buying only 2 tickets, the discount is negligible, but will add up quickly as you increase the number of tickets to buy in one transaction.

The discount only applies to each transaction up to 100 tickets. The discount does not carry over to the next transaction or next round.

 

Why can I only buy 100 tickets?

 

You can only buy a maximum of 100 tickets in one purchase, but you can make multiple purchasesin each round. There's nothing to stop you buying more tickets after your first 100.

 

If I manually create two or more tickets with the same numbers and they win, am I eligible for prizes for each ticket?

 

Yes, each ticket is treated as a separate entry to the CryptuLotto®. Keep in mind that the prizes will not be 1:1 though, as each winning ticket you have dilutes each share of the bracket's total prizes.

Hint! You can only buy tickets with the same numbers in separate purchases. In each purchase, you cannot choose two or more tickets with the same numbers and the system will give you the necessary message.

 

When is $FARTY injected to the CryptuLotto®?

 

When people buy tickets, the $FARTY they spend is added to the CryptuLotto® pot. In addition, some extra $FARTY is also may be added (injected) to the CryptuLotto® pot by Cryptu.io team.

 

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 cryptocurrency token without approving any banks or financial institutions and your own tokens are generated in decentralized method.

 

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

 

• Minting your cryptocurrency 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 cryptocurrency token without approving any banks or financial institutions and your own tokens are generated in decentralized method.

 

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

 

• Minting your cryptocurrency 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


 

 

In this instruction, you can learn how the CryptuMint® works and how to use it.

 

Token minting is the process of creating new token(s) on a blockchain with a smart contract. You can have your own token(s) with CryptuMint® platform.

As you enter the CryptuMint® webpage, you will see two plans as “Free“ and “Premium“ (as Fig. 1).

 

Fig. 1: Token Mint Plans.

 

Free Plan

 

The first plan is “Free“ that is free of charge. In this plan, the token name cannot be searched in any blockchain networks and the probability of choosing a duplicate token name is very high. Also, a free TOKEN BIRTH CERTIFICATE® (TBC®) will be Issued.

You should click on the word “Free” for entering in this plan and after that you should connect your wallet by press ”Connect Wallet” button as Fig. 2.

 

Fig. 2: Connect Wallet Button.

 

As soon as your wallet is connected, the page would be viewable as Fig. 3. In this point you will see two separate sections. The right side is the “Your Minted Tokens“ that generated by CryptuMint®, and the left side is used to mint and generate new tokens. You can also change the blockchain network in the “Select Network“ dialog box as shown in Fig. 4 by clicking the network icon shown in Fig. 3.

 

Fig. 3: Plan Appearance With Connected Wallet.

 

Fig. 4: Select Network Dialog Box.

 

Currently, there are two types of tokens that can be minted by the CryptuMint®, ERC20 standard and liquidity generator token types. By selecting the token type, you will see various fields in minting panel that you must fill in carefully to generate the token.

 

“Standard” token type minting panel consist of several fields as described in the following table:

 

Field Title Description
Token Name The name that you have chosen for your token.
Token Symbol The symbol that you have chosen for your token.
Decimals The number of decimals (portions) that is acceptable.
Total Supply The total amount of tokens that have been created or mined.

 

“Liquidity Generator” token type minting panel consist of several fields as described in the following table:

 

Field Title Description
Token Name The name that you have chosen for your token.
Token Symbol The symbol that you have chosen for your token.
Decimals The number of decimals (portions) that is acceptable.
Total Supply The total amount of tokens that have been created or mined.
Router It is your desired DEX that your liquidity is located on that decentralised exchanger. Others can exchange your token in this DEX.
Transaction Reward Fee (%) Transaction fee (%) to pay dividend to holders. This reward will be collected by your token contract and used to pay dividend to holders.
Transaction Liquidity Generator Fee (%) The percentage of each transaction that will be added to the liquidity pool.
Marketing Fee (%) Marketing Fee (%) will be sent to your wallet. Marketing Fee is used to help your project growing.
Marketing Address Your valid wallet address.

 

After all fields in minting panel are filled in carefully, you should press the ”Creat Token” button as shown in Fig. 5 to pay network fee for deploying contract and confirm the ”Deploy a Contract” transaction as shown in Fig. 6 for generating the token.

 

Fig. 5: Create Token Button.

 

Fig. 6: Deploy A Contract Confirmation Dialog Box.

 

Now you can see your minted token specifications panel as Fig. 7 consists of several fields as Certificate Code, Name, Symbol, Total Supply, Decimals, Type, Network, Contract Address, Owner Address and the Transaction Hash.

 

Fig. 7: Minted Token Specification Panel.

 

Also, you can click on your “Contract Address” as shown in Fig. 7, so the minted token would be checked in the selected network as Fig. 8.

 

Fig. 8: Minted Token Page In Blockchain Network.

 

At the buttom of minted token specification panel, your own TBC® is shown as Fig. 9 that is downloadable as a PNG file format by press “Download“ button.

 

Fig. 9: Your Own TBC®.

 

Premium Plan

 

The second plan is “Premium“ that is not free of charge. By Choosing Premium Plan, our engine will search the selected blockchain networks to find any occurrence of your token's name in order to choose a unique name. Also, a free TOKEN BIRTH CERTIFICATE® (TBC®) will be Issued and a TOKEN UNITY CERTIFICATE® (TUC®) will be available to purchase.

You should click on the word “Premium” for entering in this plan and after that you should connect your wallet by press ”Connect Wallet” button as Fig. 2.

As soon as your wallet is connected, the page would be viewable as Fig. 10. So you should select the desired “Payment Currency“ from dropdown list and press the “Pay“ button to pay CryptuMint® cost to start the premium minting.

 

Fig. 10: Premium Plan Payment Appearance.

 

The page would be viewable as Fig. 3 after confirmation of the payment transaction and due to confirmed process. Except searching the token name and symbol in various blockchain networks, the Premium and Free plans procedures are the same. So, you can use the description of all steps in Free plan.

In addition, Premium plan displays three states in the “Token Name” field filling step (after pressing the Enter key or leaving the field) to help you choose a unique name, as ”Searching Network...”, ”Exist!” and ”Available At This Moment!”. These states are not available in test networks and only works in main networks.

 

Hint! If ”Available At This Moment!” is displayed, it means you can choose a unique name for your token. And please note that the token name and the symbol search results are completely depends on the conditions of blockchain networks during search process. Cryptu.io will not be responsible for the accuracy or completeness of the results in which received from these networks.

 

Do you like to have TUC® too in which guarantees your minted token has unique name over famous crypto platforms? If the answer is “yes” you can select “Get A Certificate" as Fig. 11 after minting your own token and receiving related TBC® in Premium plan.

 

Fig. 11: Get A Certificate Section.

 

So, you will guide to search panel as fig 12. In this section, you should enter TBC®/TUC® code or contract address in the “Code/Address“ box and press “Search“ Button to start the search process.

 

Fig. 12: Search Panel.

 

Then the search results consist of the Network (primary selected), Name, Symbol and the TBC® (available if published) of minted token are shown in result section as Fig. 13. Also, in the next section, our platform will search different networks and show you in which of these networks (badges) you can get TUC®.

 

Fig. 13: Search Result Appearance.

 

The bright badge means your token TUC® is available to purchase in that network and the disabled badge means your token name is exist in that network and TUC® isn’t available for purchasing. You may choose each of available badges and the related certificate will be published after purchasing and paying the required amount of currencies.

So you can choose several networks in which the TUC® will be available in them as shown in Fig. 14. The selected badges will turn into ticks and the “Amount To Pay“ in USDT will be shown at the bottom. Now the “Purchase“ button should be pressed.

 

Fig. 14: Selected Badges Appearance.

 

You will be directed to the payment section that is shown in Fig. 15 and you should connect your wallet and choose the desired network (if nedded) for payment. Now the desired “Payment Currency“ should be selected from dropdown list as Fig. 16 that is equal to the “Amount To Pay“ and the “Pay“ button should be pressed.

 

Fig. 15: Connect Wallet Section.

 

Fig. 16: Payment Panel.

 

Since your wallet is connected and “Pay“ button is pressed according the previous steps, so you should confirm the currency transfer request as Fig. 17.

 

Fig. 17: Currency Transfer Request Dialog Box.

 

Now you can see your token TUC® specifications panel as Fig. 18 consists of several fields as Certificate Code, Name, Symbol, Network and the Contract Address. At the buttom of token TUC® specification panel, your own TUC® is shown that is downloadable as a PNG file format by press “Download“ button.

 

Fig. 18: Token TUC® Specification Panel And Your Own TUC®.

 

As it is shown in above figure, your own TUC® contains the specifications and the selected badge(s) you have purchased and your token name is unique in those network(s).

 

CryptuQuery® (Cryptu Token Query)


 

 

Cryptu Token Query (CryptuQuery®) is a comprehensive platform under Cryptu.io in which the authenticity and validity of certificates, that has been generated by Cryptu.io, can be checked. Also, if a TUC® has not been issued for your token by our website, you can purchase it through this section. The QR code of TBC®/TUC® or token contract address may be checked in CryptuQuery® then the system will show you whether TBC® or TUC® was issued for your token, and if it was issued, its authenticity can be checked.

CryptuQuery® How To Do


 

 

In this instruction, you can learn how the CryptuQuery® works and how to use it.

 

As you enter the CryptuQuery® webpage, you will see the platform as Fig. 1.

 

Fig. 1: CryptuQuery® Webpage Appearance.

 

Authenticity Check

 

You may want to check authenticity of published TBC®/TUC® by Cryptu.io in CryptuQuery®. So, you should enter Token Birth/Unity Certificate code or token contract address in related “Code/Address” box as shown in fig. 1.

If you entered Token Birth/Unity Certificate code, you only need to press the "Search" button as shown in Fig. 2 and if you entereand token contract address, you should leave the box to activate the "Network" drop down list, select correct network related to your token and then press the “Search” button as shown in Fig. 3 to start the search process.

Please remember that the correct format for entering code/address in related box must be followed, otherwise the system will show you the appropriate message.

 

Fig. 2: TBC®/TUC® Code Search.

 

Fig. 3: Token Contract Address Seacrh.

 

If TBC®/TUC® in which has been published by Cryptu.io, so the “Token Unity Certificate (TUC)” or “Token Birth Certificate (TBC)” would be in available mode in search result as shown in Fig. 4. If you press the “Available” button, you can check authenticity and validity of certificates by viewing a copy of the published certificate in PNG file format.

 

Fig. 4: CryptuQuery® Code/Address Search Result.

 

Also, remember that you can check the authenticity of published TBC®/TUC® by scanning the QR code on them.

 

Purchase TUC®

 

You may want to purchase a TUC® for your token from Cryptu.io in CryptuQuery®. So, you should enter TBC® code or contract address of your token in related “Code/Address” box as previously explained and then press the “Search” button to start the search process.

Then the search results consist of the Network (primary selected), Name, Symbol and the TBC® (available if published) of your token are shown in result section as Fig. 5. Also, in the next section, our platform will search different networks and show you in which of these networks (badges) you can get TUC®.

 

Fig. 5: Search Result Appearance.

 

The bright badge means your token TUC® is available to purchase in that network and the disabled badge means your token name is exist in that network and TUC® isn’t available for purchasing. You may choose each of available badges and the related certificate will be published after purchasing and paying the required amount of currencies.

So you can choose several networks in which the TUC® will be available in them as shown in Fig. 6. The selected badges will turn into ticks and the “Amount To Pay“ in USDT will be shown at the bottom. Now the “Purchase“ button should be pressed.

 

Fig. 6: Selected Badges Appearance.

 

You will be directed to the payment section that is shown in Fig. 7 and you should connect your wallet and choose the desired network (if nedded) for payment. Now the desired “Payment Currency“ should be selected from dropdown list as Fig. 8 that is equal to the “Amount To Pay“ and the “Pay“ button should be pressed.

 

Fig. 7: Connect Wallet Section.

 

Fig. 8: Payment Panel.

 

Since your wallet is connected and “Pay“ button is pressed according the previous steps, so you should confirm the currency transfer request as Fig. 9.

 

Fig. 9: Currency Transfer Request Dialog Box.

 

Now you can see your token TUC® specifications panel as Fig. 10 consists of several fields as Certificate Code, Name, Symbol, Network and the Contract Address. At the buttom of token TUC® specification panel, your own TUC® is shown that is downloadable as a PNG file format by press “Download“ button.

 

Fig. 10: Token TUC® Specification Panel And Your Own TUC®.

 

As it is shown in above figure, your own TUC® contains the specifications and the selected badge(s) you have purchased and your token name is unique in those network(s).

 

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 cryptocurrency, 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!