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;
}
}
Submitted on: 2025-11-05 12:32:50
Comments
Log in to comment.
No comments yet.