Stox
0x5d7335ad46585fe87946040f024019deb5f2b6d7
Verification
Verified
v0.8.28+commit.7893614a
Type
Contract
7,992 bytes
ABI entries
77
31 read · 20 write
License
none
Contract information
- Address
- 0x5d7335ad46585fe87946040f024019deb5f2b6d7
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.28+commit.7893614a
- Optimization
- Enabled
- Creator
- 0x171952905d…5331b618B4
- Creation tx
- 0x1e442971d1…36b9c9b670
Token
- Name
- Stox
- Symbol
- STOX
- Decimals
- 18
- Holders
- 7,155
- Market
- View token page →
Read contract (31)
DENOM() → uint256
MAX_TAX_BPS() → uint256
MIN_MAX_TX() → uint256
MIN_MAX_WALLET() → uint256
allowance(address, address) → uint256
automatedMarketMakerPairs(address) → bool
balanceOf(address) → uint256
buyTaxBps() → uint256
decimals() → uint8
distributor() → address
distributorShareBps() → uint256
isExcludedFromDividends(address) → bool
isExcludedFromFee(address) → bool
isExcludedFromLimits(address) → bool
limitsInEffect() → bool
liquidityShareBps() → uint256
marketingShareBps() → uint256
marketingWallet() → address
maxTransaction() → uint256
maxWallet() → uint256
name() → string
owner() → address
pendingOwner() → address
router() → address
sellTaxBps() → uint256
swapEnabled() → bool
swapTokensAtAmount() → uint256
symbol() → string
totalSupply() → uint256
tradingEnabled() → bool
uniswapV2Pair() → address
Events (9)
ApprovalLimitsRemovedOwnershipTransferStartedOwnershipTransferredSplitUpdatedSwapBackTaxesUpdatedTradingEnabledTransfer
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "_router",
"type": "address"
},
{
"internalType": "address",
"name": "_distributor",
"type": "address"
},
{
"internalType": "address",
"name": "_marketingWallet",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "allowance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "ERC20InsufficientAllowance",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "uint256",
"name": "balance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "ERC20InsufficientBalance",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "approver",
"type": "address"
}
],
"name": "ERC20InvalidApprover",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"name": "ERC20InvalidReceiver",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "ERC20InvalidSender",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "ERC20InvalidSpender",
"type": "error"
},
{
"inputs": [],
"name": "InvalidSplit",
"type": "error"
},
{
"inputs": [],
"name": "LimitTooLow",
"type": "error"
},
{
"inputs": [],
"name": "MaxTxExceeded",
"type": "error"
},
{
"inputs": [],
"name": "MaxWalletExceeded",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"inputs": [],
"name": "TaxTooHigh",
"type": "error"
},
{
"inputs": [],
"name": "TradingNotEnabled",
"type": "error"
},
{
"inputs": [],
"name": "ZeroAddress",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "LimitsRemoved",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferStarted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "distributorBps",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "liquidityBps",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "marketingBps",
"type": "uint256"
}
],
"name": "SplitUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "tokensSwapped",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "ethToDistributor",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "ethToLiquidity",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "ethToMarketing",
"type": "uint256"
}
],
"name": "SwapBack",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "buyBps",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "sellBps",
"type": "uint256"
}
],
"name": "TaxesUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "TradingEnabled",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"inputs": [],
"name": "DENOM",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_TAX_BPS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MIN_MAX_TX",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MIN_MAX_WALLET",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "acceptOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "automatedMarketMakerPairs",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "buyTaxBps",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "distributor",
"outputs": [
{
"internalType": "contract StoxDistributor",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "distributorShareBps",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "enableTrading",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "isExcludedFromDividends",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "isExcludedFromFee",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "isExcludedFromLimits",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "limitsInEffect",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "liquidityShareBps",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "manualSwapBack",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "marketingShareBps",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "marketingWallet",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "maxTransaction",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "maxWallet",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pendingOwner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "removeLimits",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "rescueETH",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "router",
"outputs": [
{
"internalType": "contract IUniswapV2Router02",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "sellTaxBps",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "pair",
"type": "address"
},
{
"internalType": "bool",
"name": "value",
"type": "bool"
}
],
"name": "setAmmPair",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "setExcludedFromDividends",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "setExcludedFromFee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "setExcludedFromLimits",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_maxTransaction",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_maxWallet",
"type": "uint256"
}
],
"name": "setLimits",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "wallet",
"type": "address"
}
],
"name": "setMarketingWallet",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_distributorBps",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_liquidityBps",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_marketingBps",
"type": "uint256"
}
],
"name": "setSplit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "enabled",
"type": "bool"
}
],
"name": "setSwapEnabled",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "setSwapTokensAtAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_buyBps",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_sellBps",
"type": "uint256"
}
],
"name": "setTaxes",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "swapEnabled",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "swapTokensAtAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "tradingEnabled",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "uniswapV2Pair",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {IUniswapV2Factory, IUniswapV2Router02} from "./interfaces/IUniswapV2.sol";
import {StoxDistributor} from "./StoxDistributor.sol";
/**
* @title Stox ($STOX)
* @notice Hold it, get paid in stocks. An independent RWA index token for
* Robinhood Chain. A 4% trade tax is collected, swapped to ETH, and split:
* 80% to the dividend distributor (buys the tokenized-stock basket for
* holders), 10% to auto-liquidity, 10% to the ops wallet.
*
* @dev Tokenomics are fully adjustable by the owner within safe caps
* (tax <= 5%), so the split can be revised as the model matures.
* OZ v5 ERC20; all transfer logic routes through `_update`.
*/
contract Stox is ERC20, Ownable2Step {
uint256 public constant DENOM = 10_000;
uint256 public constant MAX_TAX_BPS = 500; // hard cap 5% — cannot rug to a honeypot
uint256 public constant MIN_MAX_TX = 1_000_000 * 1e18; // 0.1% — limits floor
uint256 public constant MIN_MAX_WALLET = 5_000_000 * 1e18; // 0.5% — limits floor
IUniswapV2Router02 public router;
address public uniswapV2Pair;
StoxDistributor public distributor;
address public marketingWallet;
// ── taxes (basis points) ──
uint256 public buyTaxBps = 400; // 4%
uint256 public sellTaxBps = 400; // 4%
// ── split of collected tax (bps, sum = DENOM) ──
uint256 public distributorShareBps = 8_000;
uint256 public liquidityShareBps = 1_000;
uint256 public marketingShareBps = 1_000;
// ── swapback ──
bool public swapEnabled = true;
bool private inSwap;
uint256 public swapTokensAtAmount;
// ── trading / limits ──
bool public tradingEnabled;
bool public limitsInEffect = true;
uint256 public maxTransaction;
uint256 public maxWallet;
mapping(address => bool) public isExcludedFromFee;
mapping(address => bool) public isExcludedFromLimits;
mapping(address => bool) public isExcludedFromDividends;
mapping(address => bool) public automatedMarketMakerPairs;
event TradingEnabled();
event TaxesUpdated(uint256 buyBps, uint256 sellBps);
event SplitUpdated(uint256 distributorBps, uint256 liquidityBps, uint256 marketingBps);
event SwapBack(
uint256 tokensSwapped, uint256 ethToDistributor, uint256 ethToLiquidity, uint256 ethToMarketing
);
event LimitsRemoved();
error TradingNotEnabled();
error TaxTooHigh();
error InvalidSplit();
error MaxTxExceeded();
error MaxWalletExceeded();
error LimitTooLow();
error ZeroAddress();
modifier lockSwap() {
inSwap = true;
_;
inSwap = false;
}
/**
* @param _router Uniswap V2 router on Robinhood Chain.
* @param _distributor Pre-deployed StoxDistributor. After deploying this token,
* the distributor owner must call `distributor.setStox(token)` and
* `distributor.setBasket(...)` to finish wiring.
* @param _marketingWallet Ops wallet.
*/
constructor(address _router, address _distributor, address _marketingWallet)
ERC20("Stox", "STOX")
Ownable(msg.sender)
{
if (_router == address(0) || _distributor == address(0) || _marketingWallet == address(0)) {
revert ZeroAddress();
}
uint256 supply = 1_000_000_000 * 1e18;
router = IUniswapV2Router02(_router);
marketingWallet = _marketingWallet;
distributor = StoxDistributor(payable(_distributor));
// Create the STOX/WETH pair.
uniswapV2Pair = IUniswapV2Factory(router.factory()).createPair(address(this), router.WETH());
_setAmmPair(uniswapV2Pair, true);
// Defaults: 0.1% swap threshold, 1% max tx, 2% max wallet.
swapTokensAtAmount = supply / 1_000;
maxTransaction = supply / 100;
maxWallet = supply / 50;
// Exclusions.
_excludeAll(owner());
_excludeAll(address(this));
_excludeAll(_marketingWallet);
isExcludedFromFee[address(distributor)] = true;
isExcludedFromLimits[address(router)] = true;
// NB: the pair is intentionally NOT excluded from limits — the per-branch
// logic in _update applies maxTx/maxWallet correctly to buys and sells.
isExcludedFromDividends[address(this)] = true;
isExcludedFromDividends[address(distributor)] = true;
isExcludedFromDividends[uniswapV2Pair] = true;
isExcludedFromDividends[address(0)] = true;
isExcludedFromDividends[address(0xdead)] = true;
_approve(address(this), _router, type(uint256).max);
_mint(owner(), supply);
}
function _excludeAll(address a) internal {
isExcludedFromFee[a] = true;
isExcludedFromLimits[a] = true;
isExcludedFromDividends[a] = true;
}
// ── core transfer hook ──
function _update(address from, address to, uint256 amount) internal override {
if (amount == 0 || inSwap) {
super._update(from, to, amount);
return;
}
if (!tradingEnabled && !(isExcludedFromFee[from] || isExcludedFromFee[to])) {
revert TradingNotEnabled();
}
// Anti-whale limits (mint/burn skipped: from/to == 0 handled by exclusions).
if (limitsInEffect && !isExcludedFromLimits[from] && !isExcludedFromLimits[to]) {
if (automatedMarketMakerPairs[from]) {
if (amount > maxTransaction) revert MaxTxExceeded();
if (balanceOf(to) + amount > maxWallet) revert MaxWalletExceeded();
} else if (automatedMarketMakerPairs[to]) {
if (amount > maxTransaction) revert MaxTxExceeded();
} else {
if (balanceOf(to) + amount > maxWallet) revert MaxWalletExceeded();
}
}
// Swap accumulated tax on sells.
if (
swapEnabled && !inSwap && automatedMarketMakerPairs[to] && !isExcludedFromFee[from]
&& balanceOf(address(this)) >= swapTokensAtAmount
) {
_swapBack();
}
// Take fee on buys/sells (never on plain wallet-to-wallet).
uint256 fee;
bool takeFee = !isExcludedFromFee[from] && !isExcludedFromFee[to];
if (takeFee) {
if (automatedMarketMakerPairs[to]) {
fee = (amount * sellTaxBps) / DENOM;
} else if (automatedMarketMakerPairs[from]) {
fee = (amount * buyTaxBps) / DENOM;
}
}
if (fee > 0) {
super._update(from, address(this), fee);
amount -= fee;
}
super._update(from, to, amount);
_syncDividends(from);
_syncDividends(to);
}
function _syncDividends(address account) internal {
if (isExcludedFromDividends[account]) return;
try distributor.setBalance(account, balanceOf(account)) {} catch {}
}
// ── swapback / auto-liquidity ──
function _swapBack() internal lockSwap {
uint256 collected = balanceOf(address(this));
uint256 cap = swapTokensAtAmount * 20;
if (collected > cap) collected = cap;
if (collected == 0) return;
// Reserve half the liquidity share as tokens for the LP add.
uint256 liqTokens = (collected * liquidityShareBps) / DENOM / 2;
uint256 swapAmount = collected - liqTokens;
uint256 ethBefore = address(this).balance;
_swapTokensForEth(swapAmount);
uint256 ethGained = address(this).balance - ethBefore;
if (ethGained == 0) return;
// swapAmount corresponds to (DENOM - liquidityShareBps/2) parts.
uint256 denomParts = DENOM - liquidityShareBps / 2;
uint256 ethForLiq = (ethGained * (liquidityShareBps / 2)) / denomParts;
uint256 ethForMarketing = (ethGained * marketingShareBps) / denomParts;
uint256 ethForDistributor = ethGained - ethForLiq - ethForMarketing;
if (liqTokens > 0 && ethForLiq > 0) {
try router.addLiquidityETH{value: ethForLiq}(
address(this), liqTokens, 0, 0, owner(), block.timestamp
) {}
catch {
ethForDistributor += ethForLiq; // if LP add fails, redirect to holders
}
}
if (ethForMarketing > 0) {
(bool ok,) = payable(marketingWallet).call{value: ethForMarketing}("");
if (!ok) ethForDistributor += ethForMarketing;
}
if (ethForDistributor > 0) {
distributor.distribute{value: ethForDistributor}();
}
emit SwapBack(swapAmount, ethForDistributor, ethForLiq, ethForMarketing);
}
function _swapTokensForEth(uint256 tokenAmount) internal {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = router.WETH();
router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount, 0, path, address(this), block.timestamp
);
}
// ── admin ──
function enableTrading() external onlyOwner {
tradingEnabled = true;
emit TradingEnabled();
}
function setTaxes(uint256 _buyBps, uint256 _sellBps) external onlyOwner {
if (_buyBps > MAX_TAX_BPS || _sellBps > MAX_TAX_BPS) revert TaxTooHigh();
buyTaxBps = _buyBps;
sellTaxBps = _sellBps;
emit TaxesUpdated(_buyBps, _sellBps);
}
function setSplit(uint256 _distributorBps, uint256 _liquidityBps, uint256 _marketingBps)
external
onlyOwner
{
if (_distributorBps + _liquidityBps + _marketingBps != DENOM) revert InvalidSplit();
distributorShareBps = _distributorBps;
liquidityShareBps = _liquidityBps;
marketingShareBps = _marketingBps;
emit SplitUpdated(_distributorBps, _liquidityBps, _marketingBps);
}
function setSwapTokensAtAmount(uint256 amount) external onlyOwner {
swapTokensAtAmount = amount;
}
function setSwapEnabled(bool enabled) external onlyOwner {
swapEnabled = enabled;
}
function setLimits(uint256 _maxTransaction, uint256 _maxWallet) external onlyOwner {
// Floors so the owner can never freeze trading with near-zero limits.
if (_maxTransaction < MIN_MAX_TX || _maxWallet < MIN_MAX_WALLET) revert LimitTooLow();
maxTransaction = _maxTransaction;
maxWallet = _maxWallet;
}
function removeLimits() external onlyOwner {
limitsInEffect = false;
emit LimitsRemoved();
}
/// @notice Owner can manually convert accumulated tax tokens (e.g. if auto
/// swapback hasn't triggered). Cannot touch anything but the tax reserve.
function manualSwapBack() external onlyOwner {
if (balanceOf(address(this)) > 0) _swapBack();
}
function setMarketingWallet(address wallet) external onlyOwner {
if (wallet == address(0)) revert ZeroAddress();
marketingWallet = wallet;
isExcludedFromFee[wallet] = true;
}
function setExcludedFromFee(address account, bool excluded) external onlyOwner {
isExcludedFromFee[account] = excluded;
}
function setExcludedFromLimits(address account, bool excluded) external onlyOwner {
isExcludedFromLimits[account] = excluded;
}
function setExcludedFromDividends(address account, bool excluded) external onlyOwner {
isExcludedFromDividends[account] = excluded;
if (excluded) {
try distributor.setBalance(account, 0) {} catch {}
} else {
try distributor.setBalance(account, balanceOf(account)) {} catch {}
}
}
function setAmmPair(address pair, bool value) external onlyOwner {
require(pair != uniswapV2Pair, "cannot change primary pair");
_setAmmPair(pair, value);
}
function _setAmmPair(address pair, bool value) internal {
automatedMarketMakerPairs[pair] = value;
isExcludedFromDividends[pair] = value;
}
/// @notice Recover non-STOX tokens or stuck ETH accidentally sent here.
function rescueETH() external onlyOwner {
(bool ok,) = payable(owner()).call{value: address(this).balance}("");
require(ok, "rescue failed");
}
receive() external payable {}
}
Chain explorer1335msChain node82ms