SupportPass

Description:

Smart contract deployed on Ethereum.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

// Inline IERC20 interface - no imports needed
interface IERC20 {
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
    function transfer(address to, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
}

contract SupportPass {
    // Structs for clean batch data returns
    struct SupporterData {
        address supporterAddress;
        bool hasSupported;
    }
    
    struct ReferralData {
        address referrerAddress;
        uint256 totalReferrals;
    }
    
    struct ReferredSupporterData {
        address supporterAddress;
    }
    
    // USDC token contract
    IERC20 public immutable usdc;
    
    // Fixed price: $10 USDC (6 decimals)
    uint256 public constant SUPPORT_PRICE = 10 * 10**6; // 10 USDC
    
    // Track all supporters
    address[] public supporters;
    mapping(address => bool) public hasSupported;
    
    // Track all referrers
    address[] public referrers;
    mapping(address => bool) public isReferrer;
    mapping(address => uint256) public totalReferrals;
    
    // Track WHO was referred by each referrer
    mapping(address => address[]) public referredSupporters;
    
    address public owner;
    bool public paused;
    
    event Support(address indexed supporter, address indexed referrer);
    event Withdrawal(address indexed to, uint256 amount);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    event Paused(address account);
    event Unpaused(address account);
    event Referral(address indexed referrer, address indexed supporter);
    
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }
    
    modifier whenNotPaused() {
        require(!paused, "Contract is paused");
        _;
    }
    
    constructor(address _usdcAddress) {
        require(_usdcAddress != address(0), "Invalid USDC address");
        usdc = IERC20(_usdcAddress);
        owner = msg.sender;
        paused = false;
    }
    
    // WRITE FUNCTIONS
    
    function support(address referrer) external whenNotPaused {
        require(!hasSupported[msg.sender], "Already supported");
        require(referrer != msg.sender, "Cannot refer yourself");
        
        // Transfer USDC from supporter to contract
        require(
            usdc.transferFrom(msg.sender, address(this), SUPPORT_PRICE),
            "USDC transfer failed"
        );
        
        // Track supporter
        supporters.push(msg.sender);
        hasSupported[msg.sender] = true;
        
        // Track referral if valid referrer provided
        if (referrer != address(0)) {
            // Track first-time referrers
            if (!isReferrer[referrer]) {
                referrers.push(referrer);
                isReferrer[referrer] = true;
            }
            
            totalReferrals[referrer] += 1;
            referredSupporters[referrer].push(msg.sender);
            emit Referral(referrer, msg.sender);
        }
        
        emit Support(msg.sender, referrer);
    }
    
    function withdraw() external onlyOwner {
        uint256 balance = usdc.balanceOf(address(this));
        require(balance > 0, "No funds");
        
        require(usdc.transfer(owner, balance), "Transfer failed");
        
        emit Withdrawal(owner, balance);
    }
    
    function emergencyWithdraw(address recipient) external onlyOwner {
        require(recipient != address(0), "Invalid recipient");
        uint256 balance = usdc.balanceOf(address(this));
        require(balance > 0, "No funds");
        
        require(usdc.transfer(recipient, balance), "Transfer failed");
        
        emit Withdrawal(recipient, balance);
    }
    
    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "New owner is zero address");
        address oldOwner = owner;
        owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
    
    function pause() external onlyOwner {
        paused = true;
        emit Paused(msg.sender);
    }
    
    function unpause() external onlyOwner {
        paused = false;
        emit Unpaused(msg.sender);
    }
    
    // READ FUNCTIONS
    
    function getTotalSupporters() external view returns (uint256) {
        return supporters.length;
    }
    
    function getTotalReferrers() external view returns (uint256) {
        return referrers.length;
    }
    
    function getSupporterDataBatch(uint256 startIndex, uint256 count) 
        external 
        view 
        returns (SupporterData[] memory) 
    {
        require(count <= 50, "Max 50 per batch");
        
        uint256 totalSupporters = supporters.length;
        if (startIndex >= totalSupporters) {
            return new SupporterData[](0);
        }
        
        uint256 endIndex = startIndex + count;
        if (endIndex > totalSupporters) {
            endIndex = totalSupporters;
        }
        
        uint256 resultCount = endIndex - startIndex;
        SupporterData[] memory result = new SupporterData[](resultCount);
        
        for (uint256 i = 0; i < resultCount; i++) {
            address supporter = supporters[startIndex + i];
            result[i] = SupporterData({
                supporterAddress: supporter,
                hasSupported: hasSupported[supporter]
            });
        }
        
        return result;
    }
    
    function getReferralDataBatch(uint256 startIndex, uint256 count)
        external
        view
        returns (ReferralData[] memory)
    {
        require(count <= 50, "Max 50 per batch");
        
        uint256 totalReferrersCount = referrers.length;
        if (startIndex >= totalReferrersCount) {
            return new ReferralData[](0);
        }
        
        uint256 endIndex = startIndex + count;
        if (endIndex > totalReferrersCount) {
            endIndex = totalReferrersCount;
        }
        
        uint256 resultCount = endIndex - startIndex;
        ReferralData[] memory result = new ReferralData[](resultCount);
        
        for (uint256 i = 0; i < resultCount; i++) {
            address referrer = referrers[startIndex + i];
            result[i] = ReferralData({
                referrerAddress: referrer,
                totalReferrals: totalReferrals[referrer]
            });
        }
        
        return result;
    }
    
    function getReferredSupportersBatch(address referrer, uint256 startIndex, uint256 count)
        external
        view
        returns (ReferredSupporterData[] memory)
    {
        require(count <= 50, "Max 50 per batch");
        
        address[] storage referred = referredSupporters[referrer];
        uint256 totalReferred = referred.length;
        
        if (startIndex >= totalReferred) {
            return new ReferredSupporterData[](0);
        }
        
        uint256 endIndex = startIndex + count;
        if (endIndex > totalReferred) {
            endIndex = totalReferred;
        }
        
        uint256 resultCount = endIndex - startIndex;
        ReferredSupporterData[] memory result = new ReferredSupporterData[](resultCount);
        
        for (uint256 i = 0; i < resultCount; i++) {
            result[i] = ReferredSupporterData({
                supporterAddress: referredSupporters[referrer][startIndex + i]
            });
        }
        
        return result;
    }
}

Tags:
addr:0xc837b2bad89193aacf27acfa132e5af80efa0485|verified:true|block:23730518|tx:0xd69763633a985130b91d2baefb6f0c3a525402e584e8393456e37a3f9b3dc6ae|first_check:1762342368

Submitted on: 2025-11-05 12:32:50

Comments

Log in to comment.

No comments yet.