Contract Source Code:
File 1 of 1 : SonicMiner
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SonicMiner {
address public owner;
address payable public marketingWallet;
address payable public devWallet;
address payable public devRewardWallet;
uint256 public totalInvested;
uint256 public totalWithdrawn;
uint256 public totalDeposits;
uint256 public totalReferralRewards;
uint256 public totalDevReferralReinvested;
uint256 public constant BASE_DAILY_PERCENT = 50; // 5.0% daily (50 / 1000)
uint256 public constant BOOST_INCREMENT = 1; // 0.1% per day (1 / 1000)
uint256 public constant MAX_BOOST_DAYS = 10;
uint256 public constant REFERRAL_PERCENT = 80; // 8% referral reward
uint256 public constant DEV_FEE = 30; // 3% dev fee
uint256 public constant DEV_REFERRAL_BOOST = 170; // 17% boost if dev referral is used on Day 1
uint256 public constant USER_REFERRAL_BOOST = 133; // 13.3% boost if normal user referral is used on Day 1
uint256 public constant NORMAL_USER_BOOST = 50; // 5% base boost for normal investors
uint256 public constant DEV_REFERRAL_REINVEST = 20; // 2% of dev referral reinvested into contract
uint256 public constant DEV_TVL_REINVEST = 50; // 5% of dev referral goes back into TVL
uint256 public constant DEV_DIRECT_REWARD = 50; // 5% of dev referral stays in dev reward wallet
uint256[10] public TAX_SCHEDULE = [90, 80, 70, 60, 50, 40, 20, 15, 10, 5];
struct User {
uint256 invested;
uint256 withdrawn;
uint256 lastActionTime;
uint256 boostDays;
uint256 depositTime;
address referrer;
uint256 referralRewards;
bool devReferralUsed;
bool userReferralUsed;
}
mapping(address => User) public users;
mapping(address => address[]) public referredUsers;
modifier onlyOwner() {
require(msg.sender == owner, "Not authorized");
_;
}
event Deposit(address indexed user, uint256 amount);
event Withdraw(address indexed user, uint256 amount, uint256 tax);
event ReferralReward(
address indexed referrer,
address indexed user,
uint256 amount
);
event Debug(string message);
function getTaxSchedule(uint256 index) public view returns (uint256) {
require(index < TAX_SCHEDULE.length, "Index out of bounds");
return TAX_SCHEDULE[index];
}
function updateTaxSchedule(uint256[10] memory newTaxSchedule)
external
onlyOwner
{
TAX_SCHEDULE = newTaxSchedule;
}
function getReferralRewards(address user) public view returns (uint256) {
return users[user].referralRewards;
}
function getReferredUsers(address user)
public
view
returns (address[] memory)
{
return referredUsers[user];
}
function updateWallets(
address payable _marketingWallet,
address payable _devWallet,
address payable _devRewardWallet
) external onlyOwner {
marketingWallet = _marketingWallet;
devWallet = _devWallet;
devRewardWallet = _devRewardWallet;
}
function withdraw(uint256 amount) external {
User storage user = users[msg.sender];
require(
block.timestamp >= user.depositTime + 1 minutes,
"Withdrawals are restricted in the first 24 hours"
);
require(
amount <= user.invested * 3,
"Max single withdrawal limit exceeded"
);
require(
block.timestamp - user.lastActionTime >= 1 minutes,
"Can only withdraw once per day"
);
uint256 index = user.boostDays >= TAX_SCHEDULE.length
? TAX_SCHEDULE.length - 1
: user.boostDays;
uint256 taxRate = TAX_SCHEDULE[index];
uint256 taxAmount = (amount * taxRate) / 100;
uint256 netAmount = amount - taxAmount;
user.withdrawn += amount;
user.boostDays = 0;
(bool success, ) = payable(msg.sender).call{value: netAmount}("");
require(success, "Transfer failed");
user.lastActionTime = block.timestamp;
emit Withdraw(msg.sender, amount, taxAmount);
}
function compound() external {
User storage user = users[msg.sender];
require(user.invested > 0, "No investment found");
require(
block.timestamp - user.lastActionTime >= 1 minutes,
"Can only compound once per minute"
);
// Get available rewards using the same time-based calculation
uint256 earnings = getAvailableRewards(msg.sender);
user.invested += earnings;
user.boostDays = user.boostDays < MAX_BOOST_DAYS
? user.boostDays + 1
: MAX_BOOST_DAYS;
user.lastActionTime = block.timestamp;
emit Deposit(msg.sender, earnings);
}
function deposit(address referrer) external payable {
require(msg.value > 0, "Must send Sonic");
uint256 devFee = (msg.value * DEV_FEE) / 1000;
uint256 depositAmount = msg.value - devFee;
(bool devSuccess, ) = devWallet.call{value: devFee}("");
if (!devSuccess) {
emit Debug("Dev fee transfer failed");
}
User storage user = users[msg.sender];
user.invested += depositAmount;
user.lastActionTime = block.timestamp;
user.depositTime = block.timestamp;
if (
referrer != address(0) &&
referrer != msg.sender &&
users[referrer].invested > 0
) {
uint256 referralReward = (msg.value * REFERRAL_PERCENT) / 1000;
(bool refSuccess, ) = payable(referrer).call{value: referralReward}(
""
);
if (!refSuccess) {
emit Debug("Referral reward transfer failed");
}
users[referrer].referralRewards += referralReward;
totalReferralRewards += referralReward;
referredUsers[referrer].push(msg.sender);
}
totalInvested += depositAmount;
totalDeposits++;
emit Deposit(msg.sender, depositAmount);
}
/**
* @dev Calculates available rewards for a user based on their current investment and boost
* @param userAddress Address of the user to check
* @return Amount of rewards currently available
*/
function getAvailableRewards(address userAddress)
public
view
returns (uint256)
{
User storage user = users[userAddress];
if (user.invested == 0) {
return 0;
}
// Calculate time elapsed since last action (in seconds)
uint256 timeElapsed = block.timestamp - user.lastActionTime;
// Calculate daily percent with boost
uint256 dailyPercent = BASE_DAILY_PERCENT +
(user.boostDays * BOOST_INCREMENT);
// Convert daily rate to time-proportional rate
// 86400 seconds in a day
uint256 earnings = (user.invested * dailyPercent * timeElapsed) /
(86400 * 1000);
return earnings;
}
/**
* @dev Returns the current tax rate for a user based on their boost days
* @param userAddress Address of the user to check
* @return Current tax rate percentage
*/
function getCurrentTaxRate(address userAddress)
public
view
returns (uint256)
{
User storage user = users[userAddress];
uint256 index = user.boostDays >= TAX_SCHEDULE.length
? TAX_SCHEDULE.length - 1
: user.boostDays;
return TAX_SCHEDULE[index];
}
function getUserInfo(address userAddress)
public
view
returns (
uint256 invested,
uint256 withdrawn,
uint256 availableRewards,
uint256 boostDays,
uint256 currentDailyRate,
uint256 currentTaxRate,
uint256 referralRewards,
uint256 lastActionTime,
uint256 depositTime
)
{
User storage user = users[userAddress];
// Calculate daily percent with boost
uint256 dailyPercent = BASE_DAILY_PERCENT +
(user.boostDays * BOOST_INCREMENT);
// Calculate time-based rewards
uint256 timeElapsed = block.timestamp - user.lastActionTime;
uint256 earnings = 0;
if (user.invested > 0) {
// Convert daily rate to time-proportional rate (86400 seconds in a day)
earnings =
(user.invested * dailyPercent * timeElapsed) /
(86400 * 1000);
}
// Get current tax rate
uint256 index = user.boostDays >= TAX_SCHEDULE.length
? TAX_SCHEDULE.length - 1
: user.boostDays;
uint256 taxRate = TAX_SCHEDULE[index];
return (
user.invested,
user.withdrawn,
earnings,
user.boostDays,
dailyPercent,
taxRate,
user.referralRewards,
user.lastActionTime,
user.depositTime
);
}
constructor() {
owner = msg.sender;
marketingWallet = payable(0x2c5896b947882Bf265A43996bB735b247C6DA0ce);
devWallet = payable(0xc31354e0178D3B7abaa992C6aCD6929B657E6bC5);
devRewardWallet = payable(0xeB79bF0ed0eC013A45BfD3Ed2B44e81349b7e2a9);
}
}