Contract Name:
InfiniteSonicGlitch
Contract Source Code:
File 1 of 1 : InfiniteSonicGlitch
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: @openzeppelin/contracts/utils/math/SafeMath.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
// File: infinitesonicglitch.sol
pragma solidity ^0.8.20;
contract InfiniteSonicGlitch is Ownable {
using SafeMath for uint256;
string public constant name = "Infinite Sonic Glitch";
string public constant symbol = "ISG";
uint8 public constant decimals = 18;
uint256 public constant totalSupply = 100000000 * 10 ** 18; // 100M ISG, fixed supply
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
// Tax variables
uint256 public buyTaxFee = 4; // 4% tax in $S before buy
uint256 public sellTaxFee = 4; // 4% tax in $S after sell
uint256 public constant TAX_DENOMINATOR = 100;
// Special wallets
address public immutable marketingWallet;
address public immutable developmentWallet;
address public immutable liquidityWallet;
address public immutable burnWallet;
address public immutable ownerWallet;
// Tax distribution percentages
uint256 public constant REWARD_SHARE = 50;
uint256 public constant MARKETING_SHARE = 15;
uint256 public constant DEVELOPMENT_SHARE = 10;
uint256 public constant LIQUIDITY_SHARE = 10;
uint256 public constant BURN_SHARE = 10;
uint256 public constant OWNER_SHARE = 5;
// Staking variables
mapping(address => uint256) public stakedBalances;
mapping(address => uint256) public stakingStartTime;
mapping(address => uint256) public accumulatedStakingRewards; // $S rewards accrued daily for stakers
uint256 public totalStaked;
uint256 public stakingPeriod = 7 days;
uint256 public constant STAKING_BOOST = 2; // 2x rewards for stakers
// Reward variables
uint256 public rewardPool; // $S pool for rewards
uint256 public lastRewardDistribution;
uint256 public constant REWARD_INTERVAL = 24 hours;
// Holder tracking for rewards (only non-staked holders)
address[] public holders;
mapping(address => uint256) public holderIndex;
mapping(address => bool) public isHolder;
uint256 public totalEligibleSupply; // Total unstaked ISG held by eligible holders
// Trading control
bool public tradingEnabled;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event Staked(address indexed user, uint256 amount);
event Unstaked(address indexed user, uint256 amount, uint256 reward);
event RewardDistributed(address indexed user, uint256 reward);
event TaxCollected(address indexed user, uint256 amount, bool isBuy);
event TradingEnabled();
event HolderAdded(address indexed holder);
event HolderRemoved(address indexed holder);
constructor(
address _marketingWallet,
address _developmentWallet,
address _liquidityWallet,
address _burnWallet
) Ownable(msg.sender) { // Initialize Ownable with deployer as initial owner
require(_marketingWallet != address(0), "Invalid marketing wallet");
require(_developmentWallet != address(0), "Invalid development wallet");
require(_liquidityWallet != address(0), "Invalid liquidity wallet");
require(_burnWallet != address(0), "Invalid burn wallet");
_balances[msg.sender] = totalSupply;
marketingWallet = _marketingWallet;
developmentWallet = _developmentWallet;
liquidityWallet = _liquidityWallet;
burnWallet = _burnWallet;
ownerWallet = msg.sender; // Set ownerWallet to deployer, consistent with Ownable
lastRewardDistribution = block.timestamp;
if (!isExcluded(msg.sender)) {
holders.push(msg.sender);
holderIndex[msg.sender] = 0;
isHolder[msg.sender] = true;
totalEligibleSupply = totalSupply;
}
emit Transfer(address(0), msg.sender, totalSupply);
}
// Basic ERC-20 functions
function balanceOf(address account) external view returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) external returns (bool) {
require(tradingEnabled || msg.sender == owner(), "Trading not enabled");
_transfer(msg.sender, recipient, amount);
return true;
}
function approve(address spender, uint256 amount) external returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {
require(tradingEnabled || msg.sender == owner(), "Trading not enabled");
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][msg.sender];
require(currentAllowance >= amount, "Insufficient allowance");
_approve(sender, msg.sender, currentAllowance - amount);
return true;
}
function allowance(address owner, address spender) external view returns (uint256) {
return _allowances[owner][spender];
}
function _transfer(address sender, address recipient, uint256 amount) internal {
require(sender != address(0), "Transfer from zero address");
require(recipient != address(0), "Transfer to zero address");
require(_balances[sender] >= amount, "Insufficient balance");
_balances[sender] -= amount;
_balances[recipient] += amount;
updateHolderList(sender, recipient);
emit Transfer(sender, recipient, amount);
}
function _approve(address owner, address spender, uint256 amount) internal {
require(owner != address(0), "Approve from zero address");
require(spender != address(0), "Approve to zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
// Check if an address is excluded from taxes and rewards
function isExcluded(address account) public view returns (bool) {
return account == marketingWallet ||
account == developmentWallet ||
account == liquidityWallet ||
account == burnWallet ||
account == ownerWallet;
}
// Update holder list (only tracks unstaked balances for daily rewards)
function updateHolderList(address sender, address recipient) internal {
bool senderExcluded = isExcluded(sender);
bool recipientExcluded = isExcluded(recipient);
if (!senderExcluded) {
uint256 senderBalance = _balances[sender];
if (senderBalance == 0 && stakedBalances[sender] == 0 && isHolder[sender]) {
totalEligibleSupply = totalEligibleSupply.sub(_balances[sender]);
removeHolder(sender);
} else if (senderBalance > 0 && !isHolder[sender] && stakedBalances[sender] == 0) {
addHolder(sender);
totalEligibleSupply = totalEligibleSupply.add(senderBalance);
} else if (isHolder[sender] && stakedBalances[sender] == 0) {
totalEligibleSupply = totalEligibleSupply.sub(_balances[sender]).add(senderBalance);
} else if (isHolder[sender] && stakedBalances[sender] > 0) {
totalEligibleSupply = totalEligibleSupply.sub(_balances[sender]);
removeHolder(sender);
}
}
if (!recipientExcluded) {
uint256 recipientBalance = _balances[recipient];
if (recipientBalance > 0 && !isHolder[recipient] && stakedBalances[recipient] == 0) {
addHolder(recipient);
totalEligibleSupply = totalEligibleSupply.add(recipientBalance);
} else if (isHolder[recipient] && stakedBalances[recipient] == 0) {
totalEligibleSupply = totalEligibleSupply.sub(_balances[recipient]).add(recipientBalance);
} else if (isHolder[recipient] && stakedBalances[recipient] > 0) {
totalEligibleSupply = totalEligibleSupply.sub(_balances[recipient]);
removeHolder(recipient);
}
}
}
function addHolder(address holder) internal {
holders.push(holder);
holderIndex[holder] = holders.length - 1;
isHolder[holder] = true;
emit HolderAdded(holder);
}
function removeHolder(address holder) internal {
uint256 index = holderIndex[holder];
address lastHolder = holders[holders.length - 1];
holders[index] = lastHolder;
holderIndex[lastHolder] = index;
holders.pop();
delete holderIndex[holder];
isHolder[holder] = false;
emit HolderRemoved(holder);
}
// Tax collection
function collectBuyTax(uint256 isgAmount) external payable {
require(!isExcluded(msg.sender), "Excluded wallet cannot pay tax");
uint256 taxAmount = isgAmount.mul(buyTaxFee).div(TAX_DENOMINATOR);
require(msg.value >= taxAmount, "Insufficient $S for buy tax");
_distributeTax(msg.value);
emit TaxCollected(msg.sender, msg.value, true);
}
function collectSellTax(uint256 isgAmount) external payable {
require(!isExcluded(msg.sender), "Excluded wallet cannot pay tax");
uint256 taxAmount = isgAmount.mul(sellTaxFee).div(TAX_DENOMINATOR);
require(msg.value >= taxAmount, "Insufficient $S for sell tax");
_distributeTax(msg.value);
emit TaxCollected(msg.sender, msg.value, false);
}
function _distributeTax(uint256 taxAmount) internal {
uint256 rewardShare = taxAmount.mul(REWARD_SHARE).div(TAX_DENOMINATOR);
uint256 marketingShare = taxAmount.mul(MARKETING_SHARE).div(TAX_DENOMINATOR);
uint256 devShare = taxAmount.mul(DEVELOPMENT_SHARE).div(TAX_DENOMINATOR);
uint256 liqShare = taxAmount.mul(LIQUIDITY_SHARE).div(TAX_DENOMINATOR);
uint256 burnShare = taxAmount.mul(BURN_SHARE).div(TAX_DENOMINATOR);
uint256 ownerShare = taxAmount.mul(OWNER_SHARE).div(TAX_DENOMINATOR);
rewardPool += rewardShare;
_safeTransfer(marketingWallet, marketingShare);
_safeTransfer(developmentWallet, devShare);
_safeTransfer(liquidityWallet, liqShare);
_safeTransfer(burnWallet, burnShare);
_safeTransfer(ownerWallet, ownerShare);
}
// Staking functions
function stake(uint256 amount) external {
require(tradingEnabled || msg.sender == owner(), "Trading not enabled");
require(amount > 0, "Cannot stake 0");
require(_balances[msg.sender] >= amount, "Insufficient balance");
_transfer(msg.sender, address(this), amount);
stakedBalances[msg.sender] += amount;
totalStaked += amount;
if (stakingStartTime[msg.sender] == 0) stakingStartTime[msg.sender] = block.timestamp;
emit Staked(msg.sender, amount);
}
function unstake(uint256 amount) external {
require(amount > 0, "Cannot unstake 0");
require(stakedBalances[msg.sender] >= amount, "Insufficient staked balance");
require(block.timestamp >= stakingStartTime[msg.sender] + stakingPeriod, "Staking period not completed");
uint256 reward = accumulatedStakingRewards[msg.sender];
stakedBalances[msg.sender] -= amount;
totalStaked -= amount;
if (stakedBalances[msg.sender] == 0) {
stakingStartTime[msg.sender] = 0;
accumulatedStakingRewards[msg.sender] = 0; // Reset rewards if fully unstaked
}
_balances[msg.sender] += amount;
if (reward > 0 && !isExcluded(msg.sender)) {
_safeTransfer(msg.sender, reward);
emit RewardDistributed(msg.sender, reward);
}
updateHolderList(msg.sender, address(this));
emit Unstaked(msg.sender, amount, reward);
emit Transfer(address(this), msg.sender, amount);
}
// Reward distribution
function distributeRewards() external {
require(block.timestamp >= lastRewardDistribution + REWARD_INTERVAL, "24 hours not passed");
require(rewardPool > 0, "No $S to distribute");
uint256 totalReward = rewardPool;
uint256 totalWeightedSupply = totalEligibleSupply + (totalStaked * STAKING_BOOST); // Stakers get 2x weight
if (totalWeightedSupply == 0) {
lastRewardDistribution = block.timestamp;
return; // No eligible holders or stakers
}
// Distribute to non-staked holders
for (uint256 i = 0; i < holders.length; i++) {
address holder = holders[i];
uint256 balance = _balances[holder];
if (balance > 0) {
uint256 holderReward = balance.mul(totalReward).div(totalWeightedSupply);
if (holderReward > 0 && rewardPool >= holderReward) {
rewardPool -= holderReward;
_safeTransfer(holder, holderReward);
emit RewardDistributed(holder, holderReward);
}
}
}
// Calculate and reserve staking rewards
for (uint256 i = 0; i < holders.length; i++) {
address holder = holders[i];
uint256 stakedBalance = stakedBalances[holder];
if (stakedBalance > 0 && !isExcluded(holder)) {
uint256 stakerReward = stakedBalance.mul(STAKING_BOOST).mul(totalReward).div(totalWeightedSupply);
if (stakerReward > 0 && rewardPool >= stakerReward) {
rewardPool -= stakerReward;
accumulatedStakingRewards[holder] += stakerReward;
}
}
}
lastRewardDistribution = block.timestamp;
}
// Safe $S transfer
function _safeTransfer(address to, uint256 amount) internal {
(bool success, ) = to.call{value: amount}("");
require(success, "Transfer failed");
}
// Owner functions
function enableTrading() external onlyOwner {
require(!tradingEnabled, "Trading already enabled");
tradingEnabled = true;
emit TradingEnabled();
}
function setTaxFees(uint256 newBuyFee, uint256 newSellFee) external onlyOwner {
require(newBuyFee <= 10 && newSellFee <= 10, "Tax fee too high");
buyTaxFee = newBuyFee;
sellTaxFee = newSellFee;
}
function setStakingPeriod(uint256 newPeriod) external onlyOwner {
require(newPeriod >= 1 days, "Staking period too short");
stakingPeriod = newPeriod;
}
receive() external payable {
rewardPool += msg.value;
}
function getHolderCount() external view returns (uint256) {
return holders.length;
}
// View accumulated staking rewards
function getAccumulatedStakingRewards(address account) external view returns (uint256) {
return accumulatedStakingRewards[account];
}
}