Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"contracts/Refdrop.sol": {
"content": "// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.0;\r
\r
/**\r
* @title Interface for SubscriptionSystem\r
* @dev External interface - implemented by SubscriptionSystem contract\r
*/\r
interface ISubscriptionSystem {\r
function payReferralReward(address recipient, uint256 amount) external;\r
}\r
\r
/**\r
* @title ReferralSystem\r
* @dev Complete implementation of referral and reward system\r
*/\r
contract ReferralSystem {\r
address payable public owner;\r
bool public paused;\r
\r
// Access control mechanism\r
mapping(address => bool) public authorizedCallers;\r
\r
// Address of SubscriptionSystem (for payment)\r
address public subscriptionSystemAddress;\r
\r
struct ReferralConfig {\r
uint8 levels;\r
mapping(uint8 => uint8) discounts;\r
mapping(uint8 => uint8) rewards;\r
}\r
\r
struct ReferralMilestone {\r
uint256 referralCount;\r
bool isPlanSpecific;\r
uint256 planId;\r
bool isCorePlan;\r
uint256 rewardAmount;\r
bool isActive;\r
}\r
\r
struct ReferralStats {\r
address[] referredUsers;\r
mapping(uint256 => uint256) planReferralCounts;\r
mapping(address => uint8) referralLevel;\r
uint256 totalEarned;\r
uint256 totalWithdrawn;\r
uint256[] achievedMilestones;\r
uint256 rank;\r
}\r
\r
ReferralConfig public referralConfig;\r
\r
mapping(address => address) public userReferrer;\r
\r
mapping(address => uint256) public referralRewards;\r
\r
mapping(address => ReferralStats) private referralStats;\r
\r
mapping(uint256 => ReferralMilestone) public referralMilestones;\r
uint256 private nextMilestoneId = 1;\r
\r
mapping(address => mapping(uint256 => bool)) public claimedMilestones;\r
\r
// Arrays for enumeration (avoiding block scanning)\r
uint256[] private allMilestoneIds;\r
mapping(uint256 => bool) private milestoneExists;\r
\r
address[] private allReferrers;\r
mapping(address => bool) private referrerExists;\r
\r
// Track pending rewards before withdrawal\r
mapping(address => uint256) public pendingRewards;\r
\r
// Referral code system (generated from address, no transaction needed)\r
mapping(address => string) public addressToReferralCode;\r
mapping(string => address) public referralCodeToAddress;\r
\r
event ReferralPurchase(\r
address indexed referrer, \r
address indexed user, \r
uint256 indexed planId,\r
bool isCorePlan,\r
uint256 purchaseId,\r
uint256 referralLevel,\r
uint256 rewardAmount\r
);\r
\r
event ReferralRewardWithdrawn(\r
address indexed referrer, \r
uint256 amount\r
);\r
\r
event MilestoneAchieved(\r
address indexed user,\r
uint256 indexed milestoneId,\r
uint256 referralCount,\r
uint256 rewardAmount\r
);\r
\r
event MilestoneRewardClaimed(\r
address indexed user,\r
uint256 indexed milestoneId,\r
uint256 rewardAmount\r
);\r
\r
event EmergencyStatusChanged(bool paused);\r
event WithdrawnByOwner(uint256 amount);\r
\r
event AuthorizedCallerSet(address indexed caller, bool status);\r
event RankUpdated(address indexed user, uint256 oldRank, uint256 newRank);\r
event ReferralCodeRegistered(address indexed user, string referralCode);\r
event SubscriptionSystemAddressSet(address indexed newAddress);\r
\r
modifier onlyOwner() {\r
require(msg.sender == owner, "Only owner can call this function");\r
_;\r
}\r
\r
modifier whenNotPaused() {\r
require(!paused, "Contract is paused");\r
_;\r
}\r
\r
/**\r
* @dev Constructor initializes the contract with default settings\r
*/\r
constructor() {\r
owner = payable(msg.sender);\r
\r
referralConfig.levels = 2;\r
referralConfig.discounts[0] = 10;\r
referralConfig.discounts[1] = 5;\r
referralConfig.rewards[0] = 10;\r
referralConfig.rewards[1] = 2;\r
}\r
\r
/**\r
* @dev Change contract ownership\r
* @param newOwner Address of the new owner\r
*/\r
function transferOwnership(address payable newOwner) external onlyOwner {\r
require(newOwner != address(0), "New owner cannot be zero address");\r
owner = newOwner;\r
}\r
\r
/**\r
* @dev Toggle emergency pause status\r
* @param _paused New pause status\r
*/\r
function setPaused(bool _paused) external onlyOwner {\r
paused = _paused;\r
emit EmergencyStatusChanged(_paused);\r
}\r
\r
/**\r
* @dev Withdraw contract balance (owner only)\r
*/\r
function withdraw() external onlyOwner {\r
uint256 balance = address(this).balance;\r
require(balance > 0, "No balance to withdraw");\r
\r
(bool success, ) = owner.call{value: balance}("");\r
require(success, "Withdrawal failed");\r
\r
emit WithdrawnByOwner(balance);\r
}\r
\r
/**\r
* @dev Set authorized caller status\r
* @param caller Caller address\r
* @param status Authorization status\r
*/\r
function setAuthorizedCaller(address caller, bool status) external onlyOwner {\r
require(caller != address(0), "Invalid address");\r
authorizedCallers[caller] = status;\r
emit AuthorizedCallerSet(caller, status);\r
}\r
\r
/**\r
* @dev Set SubscriptionSystem contract address\r
* @param _subscriptionSystemAddress Address of the SubscriptionSystem contract\r
*/\r
function setSubscriptionSystemAddress(address _subscriptionSystemAddress) external onlyOwner {\r
require(_subscriptionSystemAddress != address(0), "Invalid address");\r
subscriptionSystemAddress = _subscriptionSystemAddress;\r
emit SubscriptionSystemAddressSet(_subscriptionSystemAddress);\r
}\r
\r
/**\r
* @dev Check if caller is authorized\r
*/\r
modifier onlyAuthorized() {\r
require(msg.sender == owner || authorizedCallers[msg.sender], "Unauthorized caller");\r
_;\r
}\r
\r
// ============= Referral Configuration Functions =============\r
/**\r
* @dev Configure the referral system levels and percentages\r
* @param _levels Number of referral levels\r
* @param _discounts Array of discount percentages for each level\r
* @param _rewards Array of reward percentages for each level\r
*/\r
function configureReferralSystem(\r
uint8 _levels,\r
uint8[] calldata _discounts,\r
uint8[] calldata _rewards\r
) \r
external \r
onlyOwner \r
{\r
require(_levels > 0 && _levels <= 5, "Levels must be between 1 and 5");\r
require(_discounts.length == _levels, "Discounts array length mismatch");\r
require(_rewards.length == _levels, "Rewards array length mismatch");\r
\r
referralConfig.levels = _levels;\r
\r
for (uint8 i = 0; i < _levels; i++) {\r
require(_discounts[i] <= 100, "Discount cannot exceed 100%");\r
require(_rewards[i] <= 100, "Reward cannot exceed 100%");\r
\r
referralConfig.discounts[i] = _discounts[i];\r
referralConfig.rewards[i] = _rewards[i];\r
}\r
}\r
\r
/**\r
* @dev Create a new referral milestone\r
* @param referralCount Number of referrals needed to achieve the milestone\r
* @param rewardAmount Reward amount in wei\r
* @param isPlanSpecific Whether this milestone is specific to a plan\r
* @param planId Plan ID if plan-specific\r
* @param isCorePlan Whether the plan is a core plan\r
* @return milestoneId ID of the newly created milestone\r
*/\r
function createReferralMilestone(\r
uint256 referralCount,\r
uint256 rewardAmount,\r
bool isPlanSpecific,\r
uint256 planId,\r
bool isCorePlan\r
) \r
external \r
onlyOwner \r
returns (uint256 milestoneId) \r
{\r
require(referralCount > 0, "Referral count must be greater than 0");\r
require(rewardAmount > 0, "Reward amount must be greater than 0");\r
\r
milestoneId = nextMilestoneId++;\r
\r
referralMilestones[milestoneId] = ReferralMilestone({\r
referralCount: referralCount,\r
isPlanSpecific: isPlanSpecific,\r
planId: planId,\r
isCorePlan: isCorePlan,\r
rewardAmount: rewardAmount,\r
isActive: true\r
});\r
\r
// Add to enumerable array\r
if (!milestoneExists[milestoneId]) {\r
allMilestoneIds.push(milestoneId);\r
milestoneExists[milestoneId] = true;\r
}\r
}\r
\r
/**\r
* @dev Toggle milestone activation status\r
* @param milestoneId ID of the milestone\r
* @param isActive New active status\r
*/\r
function setMilestoneStatus(uint256 milestoneId, bool isActive)\r
external\r
onlyOwner\r
{\r
require(milestoneId > 0 && milestoneId < nextMilestoneId, "Invalid milestone ID");\r
referralMilestones[milestoneId].isActive = isActive;\r
}\r
\r
/**\r
* @dev Update milestone referral count and reward amount\r
* @param milestoneId ID of the milestone\r
* @param referralCount New referral count\r
* @param rewardAmount New reward amount\r
*/\r
function updateMilestone(uint256 milestoneId, uint256 referralCount, uint256 rewardAmount)\r
external\r
onlyOwner\r
{\r
require(milestoneId > 0 && milestoneId < nextMilestoneId, "Invalid milestone ID");\r
require(referralCount > 0, "Referral count must be greater than 0");\r
require(rewardAmount > 0, "Reward amount must be greater than 0");\r
\r
ReferralMilestone storage milestone = referralMilestones[milestoneId];\r
milestone.referralCount = referralCount;\r
milestone.rewardAmount = rewardAmount;\r
}\r
\r
/**\r
* @dev Process referral reward for a purchase\r
* @param referrer Referrer address\r
* @param user User address\r
* @param planId Plan ID\r
* @param purchaseId Purchase ID\r
* @param originalPrice Original price of the plan\r
*/\r
function processReferralReward(\r
address referrer,\r
address user,\r
uint256 planId,\r
uint256 purchaseId,\r
uint256 originalPrice\r
) \r
external \r
onlyAuthorized\r
{\r
// If the user doesn't yet have a recorded referrer, set it from the provided referrer\r
if (userReferrer[user] == address(0) && user != referrer && referrer != address(0)) {\r
userReferrer[user] = referrer;\r
}\r
address currentReferrer = referrer;\r
bool isCorePlan = planId < 4; // Determine if it's a core plan based on ID\r
\r
uint8 level = 0;\r
\r
while (\r
currentReferrer != address(0) && \r
level < referralConfig.levels\r
) {\r
uint8 rewardPercentage = referralConfig.rewards[level];\r
\r
uint256 rewardAmount = (originalPrice * rewardPercentage) / 100;\r
\r
ReferralStats storage stats = referralStats[currentReferrer];\r
\r
bool isNewReferral = true;\r
for (uint256 i = 0; i < stats.referredUsers.length; i++) {\r
if (stats.referredUsers[i] == user) {\r
isNewReferral = false;\r
break;\r
}\r
}\r
\r
if (isNewReferral) {\r
stats.referredUsers.push(user);\r
stats.referralLevel[user] = level;\r
}\r
\r
stats.planReferralCounts[planId]++;\r
\r
stats.totalEarned += rewardAmount;\r
\r
referralRewards[currentReferrer] += rewardAmount;\r
pendingRewards[currentReferrer] += rewardAmount;\r
\r
// Add to referrers array if first time\r
if (!referrerExists[currentReferrer]) {\r
allReferrers.push(currentReferrer);\r
referrerExists[currentReferrer] = true;\r
}\r
\r
_checkMilestones(currentReferrer, planId, isCorePlan);\r
\r
// Update referrer rank\r
_updateReferrerRank(currentReferrer);\r
\r
emit ReferralPurchase(\r
currentReferrer,\r
user,\r
planId,\r
isCorePlan,\r
purchaseId,\r
level,\r
rewardAmount\r
);\r
\r
currentReferrer = userReferrer[currentReferrer];\r
level++;\r
}\r
}\r
\r
// Deprecated: manual referrer setting removed. Referrer links are now established automatically when\r
// a user makes a purchase using a referral code (the subscription contract passes the resolved referrer).\r
\r
/**\r
* @dev Generate and register referral code for user (one transaction)\r
* @param referralCode Unique referral code (generated off-chain from address)\r
*/\r
function generateReferralCode(string calldata referralCode) external {\r
require(bytes(referralCode).length >= 6 && bytes(referralCode).length <= 12, "Code must be 6-12 characters");\r
require(bytes(addressToReferralCode[msg.sender]).length == 0, "Code already registered");\r
require(referralCodeToAddress[referralCode] == address(0), "Code already taken");\r
\r
addressToReferralCode[msg.sender] = referralCode;\r
referralCodeToAddress[referralCode] = msg.sender;\r
\r
emit ReferralCodeRegistered(msg.sender, referralCode);\r
}\r
\r
/**\r
* @dev Get referral code for an address\r
* @param user User address\r
* @return Referral code (empty if not registered)\r
*/\r
function getReferralCode(address user) external view returns (string memory) {\r
return addressToReferralCode[user];\r
}\r
\r
/**\r
* @dev Resolve referral code to address\r
* @param referralCode Referral code\r
* @return User address (zero address if not found)\r
*/\r
function resolveReferralCode(string calldata referralCode) external view returns (address) {\r
return referralCodeToAddress[referralCode];\r
}\r
\r
/**\r
* @dev Check if referral code is available\r
* @param referralCode Referral code\r
* @return Whether the code is available\r
*/\r
function isReferralCodeAvailable(string calldata referralCode) external view returns (bool) {\r
return referralCodeToAddress[referralCode] == address(0);\r
}\r
\r
/**\r
* @dev Check if referrer has achieved any milestones\r
* @param referrer Referrer address\r
* @param planId Plan ID of the purchase\r
* @param isCorePlan Whether the plan is a core plan\r
*/\r
function _checkMilestones(\r
address referrer,\r
uint256 planId,\r
bool isCorePlan\r
) \r
internal \r
{\r
ReferralStats storage stats = referralStats[referrer];\r
\r
for (uint256 i = 1; i < nextMilestoneId; i++) {\r
ReferralMilestone storage milestone = referralMilestones[i];\r
\r
if (!milestone.isActive) continue;\r
\r
bool alreadyAchieved = false;\r
for (uint256 j = 0; j < stats.achievedMilestones.length; j++) {\r
if (stats.achievedMilestones[j] == i) {\r
alreadyAchieved = true;\r
break;\r
}\r
}\r
\r
if (alreadyAchieved) continue;\r
\r
if (milestone.isPlanSpecific) {\r
if (milestone.isCorePlan != isCorePlan || milestone.planId != planId) {\r
continue;\r
}\r
\r
if (stats.planReferralCounts[planId] >= milestone.referralCount) {\r
stats.achievedMilestones.push(i);\r
emit MilestoneAchieved(referrer, i, stats.planReferralCounts[planId], milestone.rewardAmount);\r
}\r
} else {\r
uint256 totalReferrals = stats.referredUsers.length;\r
if (totalReferrals >= milestone.referralCount) {\r
stats.achievedMilestones.push(i);\r
emit MilestoneAchieved(referrer, i, totalReferrals, milestone.rewardAmount);\r
}\r
}\r
}\r
}\r
\r
/**\r
* @dev Get referral discount percentage\r
* @return Discount percentage\r
*/\r
function getReferralDiscount(address /* referrer */) external view returns (uint8) {\r
return referralConfig.discounts[0];\r
}\r
\r
/**\r
* @dev Get referral reward percentage for a specific level\r
* @param level The referral level (0-based index)\r
* @return Reward percentage for the specified level\r
*/\r
function getRewardPercentageForLevel(uint8 level) external view returns (uint8) {\r
require(level < referralConfig.levels, "Invalid level");\r
return referralConfig.rewards[level];\r
}\r
\r
// ============= Referral Reward Functions =============\r
/**\r
* @dev Withdraw referral rewards (paid from SubscriptionSystem)\r
*/\r
function withdrawReferralRewards() external whenNotPaused {\r
uint256 amount = referralRewards[msg.sender];\r
require(amount > 0, "No rewards to withdraw");\r
require(subscriptionSystemAddress != address(0), "SubscriptionSystem not set");\r
\r
// Mark as withdrawn BEFORE transfer (prevent reentrancy)\r
referralRewards[msg.sender] = 0;\r
pendingRewards[msg.sender] = 0;\r
\r
referralStats[msg.sender].totalWithdrawn += amount;\r
\r
// Request payment from SubscriptionSystem\r
ISubscriptionSystem(subscriptionSystemAddress).payReferralReward(msg.sender, amount);\r
\r
emit ReferralRewardWithdrawn(msg.sender, amount);\r
}\r
\r
/**\r
* @dev Claim milestone reward (paid from SubscriptionSystem)\r
* @param milestoneId Milestone ID\r
*/\r
function claimMilestoneReward(uint256 milestoneId) external whenNotPaused {\r
require(milestoneId > 0 && milestoneId < nextMilestoneId, "Invalid milestone ID");\r
require(!claimedMilestones[msg.sender][milestoneId], "Milestone already claimed");\r
require(subscriptionSystemAddress != address(0), "SubscriptionSystem not set");\r
\r
ReferralMilestone storage milestone = referralMilestones[milestoneId];\r
require(milestone.isActive, "Milestone is not active");\r
\r
ReferralStats storage stats = referralStats[msg.sender];\r
\r
bool hasAchieved = false;\r
for (uint256 i = 0; i < stats.achievedMilestones.length; i++) {\r
if (stats.achievedMilestones[i] == milestoneId) {\r
hasAchieved = true;\r
break;\r
}\r
}\r
\r
require(hasAchieved, "Milestone not achieved");\r
\r
// Mark as claimed BEFORE transfer (prevent reentrancy)\r
claimedMilestones[msg.sender][milestoneId] = true;\r
\r
uint256 rewardAmount = milestone.rewardAmount;\r
\r
stats.totalWithdrawn += rewardAmount;\r
\r
// Request payment from SubscriptionSystem\r
ISubscriptionSystem(subscriptionSystemAddress).payReferralReward(msg.sender, rewardAmount);\r
\r
emit MilestoneRewardClaimed(msg.sender, milestoneId, rewardAmount);\r
}\r
\r
// ============= Query Functions =============\r
/**\r
* @dev Get referral statistics for a user\r
* @param user User address\r
* @return totalReferrals Total number of referrals\r
* @return totalEarned Total amount earned\r
* @return totalWithdrawn Total amount withdrawn\r
* @return referralCount Array of referral counts by plan\r
*/\r
function getReferralStats(address user) \r
external \r
view \r
returns (\r
uint256 totalReferrals,\r
uint256 totalEarned,\r
uint256 totalWithdrawn,\r
uint256[] memory referralCount\r
) \r
{\r
ReferralStats storage stats = referralStats[user];\r
\r
totalReferrals = stats.referredUsers.length;\r
totalEarned = stats.totalEarned;\r
totalWithdrawn = stats.totalWithdrawn;\r
\r
// Use a dynamic array since we don't know plan IDs in this contract\r
uint256[] memory planIds = new uint256[](100); // Example size, adjust as needed\r
uint256 count = 0;\r
\r
for (uint256 i = 0; i < 4; i++) {\r
if (stats.planReferralCounts[i] > 0) {\r
planIds[count++] = i;\r
}\r
}\r
\r
for (uint256 i = 100; i < 1000; i++) { // Assuming max custom plan ID is 999\r
if (stats.planReferralCounts[i] > 0) {\r
planIds[count++] = i;\r
}\r
}\r
\r
referralCount = new uint256[](count);\r
for (uint256 i = 0; i < count; i++) {\r
referralCount[i] = stats.planReferralCounts[planIds[i]];\r
}\r
}\r
\r
/**\r
* @dev Get referral rewards balance\r
* @param referrer Referrer address\r
* @return Pending rewards amount\r
*/\r
function getReferralRewards(address referrer) external view returns (uint256) {\r
return referralRewards[referrer];\r
}\r
\r
/**\r
* @dev Get user's achieved milestones\r
* @param user User address\r
* @return achievedMilestoneIds Array of achieved milestone IDs\r
* @return claimedStatus Array of whether each milestone has been claimed\r
*/\r
function getUserMilestones(address user)\r
external\r
view\r
returns (\r
uint256[] memory achievedMilestoneIds,\r
bool[] memory claimedStatus\r
)\r
{\r
ReferralStats storage stats = referralStats[user];\r
uint256[] memory milestoneIds = stats.achievedMilestones;\r
\r
achievedMilestoneIds = milestoneIds;\r
claimedStatus = new bool[](milestoneIds.length);\r
\r
for (uint256 i = 0; i < milestoneIds.length; i++) {\r
claimedStatus[i] = claimedMilestones[user][milestoneIds[i]];\r
}\r
}\r
\r
/**\r
* @dev Update referrer rank based on total referrals and earnings\r
* @param referrer Referrer address\r
*/\r
function _updateReferrerRank(address referrer) internal {\r
ReferralStats storage stats = referralStats[referrer];\r
\r
uint256 oldRank = stats.rank;\r
uint256 newRank = 0;\r
\r
// Ranking based on number of referrals and earned amount\r
uint256 referralCount = stats.referredUsers.length;\r
\r
if (referralCount >= 100) {\r
newRank = 5; // Diamond\r
} else if (referralCount >= 1000) {\r
newRank = 4; // Platinum\r
} else if (referralCount >= 250) {\r
newRank = 3; // Gold\r
} else if (referralCount >= 50) {\r
newRank = 2; // Silver\r
} else if (referralCount >= 5) {\r
newRank = 1; // Bronze\r
}\r
\r
// If rank has changed, we update it\r
if (newRank != oldRank) {\r
stats.rank = newRank;\r
emit RankUpdated(referrer, oldRank, newRank);\r
}\r
}\r
\r
/**\r
* @dev Update all referrers ranks (for admin use)\r
* @param referrers Array of referrer addresses\r
*/\r
function updateReferrersRanks(address[] calldata referrers) external onlyOwner {\r
for (uint256 i = 0; i < referrers.length; i++) {\r
_updateReferrerRank(referrers[i]);\r
}\r
}\r
\r
/**\r
* @dev Get referrer rank\r
* @param referrer Referrer address\r
* @return Referrer rank (0-5)\r
*/\r
function getReferrerRank(address referrer) external view returns (uint256) {\r
return referralStats[referrer].rank;\r
}\r
\r
// ============= Enumeration Functions (No Block Scanning) =============\r
/**\r
* @dev Get all milestone IDs\r
* @return Array of all milestone IDs\r
*/\r
function getAllMilestoneIds() external view returns (uint256[] memory) {\r
return allMilestoneIds;\r
}\r
\r
/**\r
* @dev Get total number of milestones\r
* @return Total milestone count\r
*/\r
function getMilestoneCount() external view returns (uint256) {\r
return allMilestoneIds.length;\r
}\r
\r
/**\r
* @dev Get complete milestone details\r
* @param milestoneId Milestone ID\r
* @return referralCount Required referral count\r
* @return isPlanSpecific Whether plan specific\r
* @return planId Plan ID if plan specific\r
* @return isCorePlan Whether core plan\r
* @return rewardAmount Reward amount\r
* @return isActive Whether active\r
*/\r
function getMilestoneDetails(uint256 milestoneId)\r
external\r
view\r
returns (\r
uint256 referralCount,\r
bool isPlanSpecific,\r
uint256 planId,\r
bool isCorePlan,\r
uint256 rewardAmount,\r
bool isActive\r
)\r
{\r
require(milestoneId > 0 && milestoneId < nextMilestoneId, "Invalid milestone ID");\r
ReferralMilestone storage milestone = referralMilestones[milestoneId];\r
return (\r
milestone.referralCount,\r
milestone.isPlanSpecific,\r
milestone.planId,\r
milestone.isCorePlan,\r
milestone.rewardAmount,\r
milestone.isActive\r
);\r
}\r
\r
/**\r
* @dev Get all referrers\r
* @return Array of all referrer addresses\r
*/\r
function getAllReferrers() external view returns (address[] memory) {\r
return allReferrers;\r
}\r
\r
/**\r
* @dev Get total number of referrers\r
* @return Total referrer count\r
*/\r
function getReferrerCount() external view returns (uint256) {\r
return allReferrers.length;\r
}\r
\r
/**\r
* @dev Get user's referred users list\r
* @param user User address\r
* @return Array of referred user addresses\r
*/\r
function getReferredUsers(address user) external view returns (address[] memory) {\r
return referralStats[user].referredUsers;\r
}\r
\r
/**\r
* @dev Get complete referral reward info\r
* @param referrer Referrer address\r
* @return totalEarned Total amount earned\r
* @return totalWithdrawn Total amount withdrawn\r
* @return pendingAmount Pending withdrawal amount\r
* @return availableAmount Available to withdraw now\r
*/\r
function getReferralRewardDetails(address referrer)\r
external\r
view\r
returns (\r
uint256 totalEarned,\r
uint256 totalWithdrawn,\r
uint256 pendingAmount,\r
uint256 availableAmount\r
)\r
{\r
ReferralStats storage stats = referralStats[referrer];\r
totalEarned = stats.totalEarned;\r
totalWithdrawn = stats.totalWithdrawn;\r
pendingAmount = pendingRewards[referrer];\r
availableAmount = referralRewards[referrer];\r
}\r
\r
/**\r
* @dev Get user's complete referral info\r
* @param user User address\r
* @return referredCount Total referred users count\r
* @return totalEarned Total earned amount\r
* @return totalWithdrawn Total withdrawn amount\r
* @return availableRewards Available rewards to withdraw\r
* @return rank User rank\r
* @return achievedMilestoneCount Number of achieved milestones\r
*/\r
function getUserReferralInfo(address user)\r
external\r
view\r
returns (\r
uint256 referredCount,\r
uint256 totalEarned,\r
uint256 totalWithdrawn,\r
uint256 availableRewards,\r
uint256 rank,\r
uint256 achievedMilestoneCount\r
)\r
{\r
ReferralStats storage stats = referralStats[user];\r
return (\r
stats.referredUsers.length,\r
stats.totalEarned,\r
stats.totalWithdrawn,\r
referralRewards[user],\r
stats.rank,\r
stats.achievedMilestones.length\r
);\r
}\r
\r
/**\r
* @dev Receive function to accept ETH payments\r
*/\r
receive() external payable {}\r
}"
}
},
"settings": {
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": [],
"evmVersion": "cancun"
}
}}
Submitted on: 2025-10-29 09:42:08
Comments
Log in to comment.
No comments yet.