Untitled

 avatar
unknown
plain_text
15 days ago
6.2 kB
4
Indexable
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/security/Pausable.sol";

contract UniLevelReferral is Ownable, ReentrancyGuard, Pausable {
    // Constants
    uint256 public constant LEVEL_COUNT = 5;
    uint256 public constant MIN_DEPOSIT = 0.1 ether;
    
    // Percentages for each level (40%, 25%, 15%, 12%, 8%)
    uint256[LEVEL_COUNT] public levelPercentages = [40, 25, 15, 12, 8];
    
    // Structs
    struct User {
        address referrer;
        address[] referrals;
        uint256 totalEarnings;
        uint256 pendingRewards;
        bool isRegistered;
        uint256 joinedAt;
    }
    
    // State variables
    mapping(address => User) public users;
    mapping(address => mapping(uint256 => address[])) public referralsByLevel;
    uint256 public totalUsers;
    uint256 public totalDistributed;
    uint256 public minimalPayout = 0.01 ether;

    // Events
    event UserRegistered(address indexed user, address indexed referrer);
    event ReferralPayout(address indexed user, address indexed referrer, uint256 amount, uint256 level);
    event FundsDeposited(address indexed depositor, uint256 amount);
    event FundsWithdrawn(address indexed owner, uint256 amount);
    event RewardsClaimed(address indexed user, uint256 amount);
    
    // Modifiers
    modifier onlyRegistered() {
        require(users[msg.sender].isRegistered, "User not registered");
        _;
    }
    
    // Constructor
    constructor() {
        // Register contract deployer
        users[msg.sender].isRegistered = true;
        users[msg.sender].joinedAt = block.timestamp;
        totalUsers++;
    }
    
    // External functions
    function register(address referrer) external {
        require(!users[msg.sender].isRegistered, "Already registered");
        require(referrer != msg.sender, "Cannot refer yourself");
        require(users[referrer].isRegistered, "Referrer not registered");
        
        users[msg.sender] = User({
            referrer: referrer,
            referrals: new address[](0),
            totalEarnings: 0,
            pendingRewards: 0,
            isRegistered: true,
            joinedAt: block.timestamp
        });
        
        users[referrer].referrals.push(msg.sender);
        _updateReferralNetwork(msg.sender, referrer);
        
        totalUsers++;
        emit UserRegistered(msg.sender, referrer);
    }
    
    function depositFunds() external payable onlyOwner {
        require(msg.value >= MIN_DEPOSIT, "Deposit too small");
        emit FundsDeposited(msg.sender, msg.value);
    }
    
    function withdrawFunds(uint256 amount) external onlyOwner {
        require(amount <= address(this).balance, "Insufficient contract balance");
        (bool success, ) = owner().call{value: amount}("");
        require(success, "Transfer failed");
        emit FundsWithdrawn(owner(), amount);
    }
    
    function processTransaction(address user, uint256 amount) external onlyOwner whenNotPaused nonReentrant {
        require(users[user].isRegistered, "User not registered");
        require(amount > 0, "Amount must be positive");
        require(address(this).balance >= amount, "Insufficient contract balance");
        
        address current = users[user].referrer;
        uint256 remaining = amount;
        
        for(uint256 i = 0; i < LEVEL_COUNT && current != address(0); i++) {
            if(!users[current].isRegistered) break;
            
            uint256 levelReward = (amount * levelPercentages[i]) / 100;
            if(levelReward > remaining) break;
            
            users[current].pendingRewards += levelReward;
            users[current].totalEarnings += levelReward;
            remaining -= levelReward;
            
            emit ReferralPayout(user, current, levelReward, i + 1);
            current = users[current].referrer;
        }
        
        totalDistributed += (amount - remaining);
    }
    
    function claimRewards() external nonReentrant onlyRegistered {
        uint256 rewards = users[msg.sender].pendingRewards;
        require(rewards >= minimalPayout, "Reward too small");
        require(address(this).balance >= rewards, "Insufficient contract balance");
        
        users[msg.sender].pendingRewards = 0;
        (bool success, ) = msg.sender.call{value: rewards}("");
        require(success, "Transfer failed");
        
        emit RewardsClaimed(msg.sender, rewards);
    }
    
    // View functions
    function getUserInfo(address user) external view returns (
        address referrer,
        uint256 referralCount,
        uint256 totalEarnings,
        uint256 pendingRewards,
        uint256 joinedAt
    ) {
        User storage userData = users[user];
        return (
            userData.referrer,
            userData.referrals.length,
            userData.totalEarnings,
            userData.pendingRewards,
            userData.joinedAt
        );
    }
    
    function getReferralsByLevel(address user, uint256 level) external view returns (address[] memory) {
        return referralsByLevel[user][level];
    }
    
    function getContractBalance() external view returns (uint256) {
        return address(this).balance;
    }
    
    // Internal functions
    function _updateReferralNetwork(address user, address referrer) internal {
        address current = referrer;
        uint256 level = 1;
        
        while(current != address(0) && level <= LEVEL_COUNT) {
            referralsByLevel[current][level-1].push(user);
            current = users[current].referrer;
            level++;
        }
    }
    
    // Admin functions
    function setMinimalPayout(uint256 amount) external onlyOwner {
        require(amount > 0, "Invalid amount");
        minimalPayout = amount;
    }
    
    function pause() external onlyOwner {
        _pause();
    }
    
    function unpause() external onlyOwner {
        _unpause();
    }
    
    // Fallback and receive functions
    receive() external payable {
        emit FundsDeposited(msg.sender, msg.value);
    }
}
Editor is loading...
Leave a Comment