文件 1 的 1:CatDoge.sol
pragma solidity 0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this;
return msg.data;
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
interface IERC20Metadata is IERC20{
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
_balances[to] += amount;
}
emit Transfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply += amount;
unchecked {
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
}
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
}
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() external virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
}
interface ILpPair {
function sync() external;
function mint(address to) external returns (uint liquidity);
}
interface IDexRouter {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function swapExactTokensForETHSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}
interface IDexFactory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, 'SafeMath: addition overflow');
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, 'SafeMath: subtraction overflow');
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, 'SafeMath: multiplication overflow');
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, 'SafeMath: division by zero');
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, 'SafeMath: modulo by zero');
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x < y ? x : y;
}
function sqrt(uint256 y) internal pure returns (uint256 z) {
if (y > 3) {
z = y;
uint256 x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
}
library SafeMathInt {
int256 private constant MIN_INT256 = int256(1) << 255;
int256 private constant MAX_INT256 = ~(int256(1) << 255);
function mul(int256 a, int256 b) internal pure returns (int256) {
int256 c = a * b;
require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
require((b == 0) || (c / b == a));
return c;
}
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != -1 || a != MIN_INT256);
return a / b;
}
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a));
return c;
}
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a));
return c;
}
function abs(int256 a) internal pure returns (int256) {
require(a != MIN_INT256);
return a < 0 ? -a : a;
}
function toUint256Safe(int256 a) internal pure returns (uint256) {
require(a >= 0);
return uint256(a);
}
}
library SafeMathUint {
function toInt256Safe(uint256 a) internal pure returns (int256) {
int256 b = int256(a);
require(b >= 0);
return b;
}
}
interface DividendPayingContractOptionalInterface {
function withdrawableDividendOf(address _owner) external view returns(uint256);
function withdrawnDividendOf(address _owner) external view returns(uint256);
function accumulativeDividendOf(address _owner) external view returns(uint256);
}
interface DividendPayingContractInterface {
function dividendOf(address _owner) external view returns(uint256);
function distributeDividends() external payable;
function withdrawDividend() external;
event DividendsDistributed(
address indexed from,
uint256 weiAmount
);
event DividendWithdrawn(
address indexed to,
uint256 weiAmount
);
}
contract DividendPayingContract is DividendPayingContractInterface, DividendPayingContractOptionalInterface, Ownable {
using SafeMath for uint256;
using SafeMathUint for uint256;
using SafeMathInt for int256;
uint256 constant internal magnitude = 2**128;
uint256 internal magnifiedDividendPerShare;
mapping(address => int256) internal magnifiedDividendCorrections;
mapping(address => uint256) internal withdrawnDividends;
mapping (address => uint256) public holderBalance;
uint256 public totalBalance;
uint256 public totalDividendsDistributed;
receive() external payable {
distributeDividends();
}
function distributeDividends() public override payable {
if(totalBalance > 0 && msg.value > 0){
magnifiedDividendPerShare = magnifiedDividendPerShare.add(
(msg.value).mul(magnitude) / totalBalance
);
emit DividendsDistributed(msg.sender, msg.value);
totalDividendsDistributed = totalDividendsDistributed.add(msg.value);
}
}
function withdrawDividend() external virtual override {
_withdrawDividendOfUser(payable(msg.sender));
}
function _withdrawDividendOfUser(address payable user) internal returns (uint256) {
uint256 _withdrawableDividend = withdrawableDividendOf(user);
if (_withdrawableDividend > 0) {
withdrawnDividends[user] = withdrawnDividends[user].add(_withdrawableDividend);
emit DividendWithdrawn(user, _withdrawableDividend);
(bool success,) = user.call{value: _withdrawableDividend}("");
if(!success) {
withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend);
return 0;
}
return _withdrawableDividend;
}
return 0;
}
function withdrawDividendOfUserForCompound(address payable user) external onlyOwner returns (uint256 _withdrawableDividend) {
_withdrawableDividend = withdrawableDividendOf(user);
if (_withdrawableDividend > 0) {
withdrawnDividends[user] = withdrawnDividends[user] + _withdrawableDividend;
emit DividendWithdrawn(user, _withdrawableDividend);
}
(bool success,) = owner().call{value: _withdrawableDividend}("");
if(!success) {
withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend);
return 0;
}
}
function dividendOf(address _owner) external view override returns(uint256) {
return withdrawableDividendOf(_owner);
}
function withdrawableDividendOf(address _owner) public view override returns(uint256) {
return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
}
function withdrawnDividendOf(address _owner) external view override returns(uint256) {
return withdrawnDividends[_owner];
}
function accumulativeDividendOf(address _owner) public view override returns(uint256) {
return magnifiedDividendPerShare.mul(holderBalance[_owner]).toInt256Safe()
.add(magnifiedDividendCorrections[_owner]).toUint256Safe() / magnitude;
}
function _increase(address account, uint256 value) internal {
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
.sub( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
}
function _reduce(address account, uint256 value) internal {
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
.add( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
}
function _setBalance(address account, uint256 newBalance) internal {
uint256 currentBalance = holderBalance[account];
holderBalance[account] = newBalance;
if(newBalance > currentBalance) {
uint256 increaseAmount = newBalance.sub(currentBalance);
_increase(account, increaseAmount);
totalBalance += increaseAmount;
} else if(newBalance < currentBalance) {
uint256 reduceAmount = currentBalance.sub(newBalance);
_reduce(account, reduceAmount);
totalBalance -= reduceAmount;
}
}
}
contract DividendTracker is DividendPayingContract {
event Claim(address indexed account, uint256 amount, bool indexed automatic);
mapping (address => bool) public excludedFromDividends;
constructor() {}
function getAccount(address _account)
public view returns (
address account,
uint256 withdrawableDividends,
uint256 totalDividends,
uint256 balance) {
account = _account;
withdrawableDividends = withdrawableDividendOf(account);
totalDividends = accumulativeDividendOf(account);
balance = holderBalance[account];
}
function setBalance(address payable account, uint256 newBalance) external onlyOwner {
if(excludedFromDividends[account]) {
return;
}
_setBalance(account, newBalance);
processAccount(account, true);
}
function processAccount(address payable account, bool automatic) public onlyOwner returns (bool) {
uint256 amount = _withdrawDividendOfUser(account);
if(amount > 0) {
emit Claim(account, amount, automatic);
return true;
}
return false;
}
function getTotalDividendsDistributed() external view returns (uint256) {
return totalDividendsDistributed;
}
function dividendTokenBalanceOf(address account) public view returns (uint256) {
return holderBalance[account];
}
function getNumberOfDividends() external view returns(uint256) {
return totalBalance;
}
function excludeFromDividends(address account) external onlyOwner {
excludedFromDividends[account] = true;
_setBalance(account, 0);
}
function includeInDividends(address account) external onlyOwner {
require(excludedFromDividends[account]);
excludedFromDividends[account] = false;
_setBalance(account, IERC20(owner()).balanceOf(account));
}
}
interface IWETH {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
}
contract CatDoge is ERC20, Ownable {
mapping (address => bool) public exemptFromFees;
mapping (address => bool) public exemptFromLimits;
bool public tradingAllowed;
mapping (address => bool) public isAMMPair;
address public marketingAddress;
DividendTracker public dividendTracker;
Taxes public buyTax;
Taxes public sellTax;
TokensForTax public tokensForTax;
bool public limited = true;
uint256 public swapTokensAtAmt;
address public lpPair;
IDexRouter internal dexRouter;
IWETH internal immutable WETH;
mapping(address => uint256) private _holderLastTransferBlock;
bool public transferDelayEnabled = true;
mapping(uint256 => mapping(uint256 => uint256)) public gweiMapping;
TxLimits public txLimits;
uint64 public constant FEE_DIVISOR = 10000;
struct TxLimits {
uint128 transactionLimit;
uint128 walletLimit;
}
struct Taxes {
uint48 marketingTax;
uint48 revShareTax;
uint48 totalTax;
}
struct TokensForTax {
uint64 tokensForMarketing;
uint64 tokensForRevShare;
bool gasSaver;
}
uint256 public launchTime;
bool public dynamicTaxOn;
event UpdatedTransactionLimit(uint newMax);
event UpdatedWalletLimit(uint newMax);
event SetExemptFromFees(address _address, bool _isExempt);
event SetExemptFromLimits(address _address, bool _isExempt);
event RemovedLimits();
event UpdatedBuyTax(uint newAmt);
event UpdatedSellTax(uint newAmt);
constructor()
ERC20("CatDoge", "CDETH")
{
address _v2Router;
if(block.chainid == 1){
_v2Router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
} else if(block.chainid == 5){
_v2Router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
} else {
revert("Chain not configured");
}
dividendTracker = new DividendTracker();
dynamicTaxOn = true;
dexRouter = IDexRouter(_v2Router);
marketingAddress = 0x56D162Db97b099bc71cF71eEA5F59c1dC511c837;
address buyBackAddress = 0x44c5Cb3a16B4D46F47cAc68121dd3f64b7bfedC9;
uint256 _totalSupply = 333_420_069 * 1e18;
_mint(buyBackAddress, _totalSupply * 4 / 100);
_mint(marketingAddress, _totalSupply * 4 / 100);
_mint(address(this), 223_391_446 * 1e18);
_mint(msg.sender, _totalSupply - balanceOf(marketingAddress) - balanceOf(buyBackAddress) - balanceOf(address(this)));
dividendTracker.setBalance(payable(buyBackAddress), balanceOf(buyBackAddress));
txLimits.transactionLimit = uint128(totalSupply() * 1 / 100);
txLimits.walletLimit = uint128(totalSupply() * 2 / 100);
swapTokensAtAmt = totalSupply() * 25 / 100000;
buyTax.marketingTax = 900;
buyTax.revShareTax = 0;
buyTax.totalTax = buyTax.marketingTax + buyTax.revShareTax;
sellTax.marketingTax = 2000;
sellTax.revShareTax = 0;
sellTax.totalTax = sellTax.marketingTax + sellTax.revShareTax;
tokensForTax.gasSaver = true;
WETH = IWETH(dexRouter.WETH());
lpPair = IDexFactory(dexRouter.factory()).createPair(address(this), address(WETH));
isAMMPair[lpPair] = true;
exemptFromLimits[lpPair] = true;
exemptFromLimits[msg.sender] = true;
exemptFromLimits[address(this)] = true;
exemptFromFees[msg.sender] = true;
exemptFromFees[address(this)] = true;
dividendTracker.excludeFromDividends(address(this));
dividendTracker.excludeFromDividends(address(lpPair));
dividendTracker.excludeFromDividends(msg.sender);
dividendTracker.excludeFromDividends(marketingAddress);
_approve(address(this), address(dexRouter), type(uint256).max);
_approve(address(msg.sender), address(dexRouter), totalSupply());
}
function _transfer(
address from,
address to,
uint256 amount
) internal virtual override {
if(!exemptFromFees[from] && !exemptFromFees[to]){
require(tradingAllowed, "Trading not active");
checkLimits(from, to, amount);
amount -= handleTax(from, to, amount);
}
super._transfer(from,to,amount);
dividendTracker.setBalance(payable(to), balanceOf(to));
dividendTracker.setBalance(payable(from), balanceOf(from));
}
function checkLimits(address from, address to, uint256 amount) internal {
if(limited){
bool exFromLimitsTo = exemptFromLimits[to];
uint256 balanceOfTo = balanceOf(to);
TxLimits memory _txLimits = txLimits;
if (isAMMPair[from] && !exFromLimitsTo) {
require(amount <= _txLimits.transactionLimit, "Max Txn");
require(amount + balanceOfTo <= _txLimits.walletLimit, "Max Wallet");
}
else if (isAMMPair[to] && !exemptFromLimits[from]) {
require(amount <= _txLimits.transactionLimit, "Max Txn");
}
else if(!exFromLimitsTo) {
require(amount + balanceOfTo <= _txLimits.walletLimit, "Max Wallet");
}
if (transferDelayEnabled){
if (to != address(dexRouter) && to != address(lpPair)){
require(_holderLastTransferBlock[tx.origin] < block.number, "Transfer Delay enabled");
require(tx.origin == to, "no buying to external wallets yet");
_holderLastTransferBlock[tx.origin] = block.number;
if(launchTime + 60 >= block.timestamp){
require(gweiMapping[tx.gasprice][amount] < block.number, "Dupe Txn");
gweiMapping[tx.gasprice][amount] = block.number;
}
}
}
}
}
function handleTax(address from, address to, uint256 amount) internal returns (uint256){
if(balanceOf(address(this)) >= swapTokensAtAmt && !isAMMPair[from]) {
convertTaxes();
}
if(dynamicTaxOn){
setInternalTaxes();
}
uint128 tax = 0;
Taxes memory taxes;
if (isAMMPair[to]){
taxes = sellTax;
} else if(isAMMPair[from]){
taxes = buyTax;
}
if(taxes.totalTax > 0){
TokensForTax memory tokensForTaxUpdate = tokensForTax;
tax = uint128(amount * taxes.totalTax / FEE_DIVISOR);
tokensForTaxUpdate.tokensForMarketing += uint64(tax * taxes.marketingTax / taxes.totalTax / 1e9);
tokensForTaxUpdate.tokensForRevShare += uint64(tax * taxes.revShareTax / taxes.totalTax / 1e9);
tokensForTax = tokensForTaxUpdate;
super._transfer(from, address(this), tax);
}
return tax;
}
function swapTokensForETH(uint256 tokenAmt) private {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = address(WETH);
dexRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmt,
0,
path,
address(this),
block.timestamp
);
}
function convertTaxes() private {
uint256 contractBalance = balanceOf(address(this));
TokensForTax memory tokensForTaxMem = tokensForTax;
uint256 totalTokensToSwap = tokensForTaxMem.tokensForMarketing + tokensForTaxMem.tokensForRevShare;
if(contractBalance == 0 || totalTokensToSwap == 0) {return;}
if(contractBalance > swapTokensAtAmt * 40){
contractBalance = swapTokensAtAmt * 40;
}
if(contractBalance > 0){
swapTokensForETH(contractBalance);
uint256 ethBalance = address(this).balance;
bool success;
if(tokensForTaxMem.tokensForRevShare > 0){
(success,) = address(dividendTracker).call{value: ethBalance * tokensForTaxMem.tokensForRevShare/ totalTokensToSwap}("");
}
ethBalance = address(this).balance;
if(ethBalance > 0){
(success,) = marketingAddress.call{value: ethBalance}("");
}
}
tokensForTaxMem.tokensForMarketing = 0;
tokensForTaxMem.tokensForRevShare = 0;
tokensForTax = tokensForTaxMem;
}
function setExemptFromFee(address _address, bool _isExempt) external onlyOwner {
require(_address != address(0), "Zero Address");
require(_address != address(this), "Cannot unexempt contract");
exemptFromFees[_address] = _isExempt;
emit SetExemptFromFees(_address, _isExempt);
}
function setExemptFromLimit(address _address, bool _isExempt) external onlyOwner {
require(_address != address(0), "Zero Address");
if(!_isExempt){
require(_address != lpPair, "Cannot remove pair");
}
exemptFromLimits[_address] = _isExempt;
emit SetExemptFromLimits(_address, _isExempt);
}
function updateTransactionLimit(uint128 newNumInTokens) external onlyOwner {
require(newNumInTokens >= (totalSupply() * 1 / 100)/(10**decimals()), "Too low");
txLimits.transactionLimit = uint128(newNumInTokens * (10**decimals()));
emit UpdatedTransactionLimit(txLimits.transactionLimit);
}
function updateWalletLimit(uint128 newNumInTokens) external onlyOwner {
require(newNumInTokens >= (totalSupply() * 1 / 100)/(10**decimals()), "Too low");
txLimits.walletLimit = uint128(newNumInTokens * (10**decimals()));
emit UpdatedWalletLimit(txLimits.walletLimit);
}
function updateSwapTokensAmt(uint256 newAmount) external onlyOwner {
require(newAmount >= (totalSupply() * 1) / 100000, "Swap amount cannot be lower than 0.001% total supply.");
require(newAmount <= (totalSupply() * 5) / 1000, "Swap amount cannot be higher than 0.5% total supply.");
swapTokensAtAmt = newAmount;
}
function updateBuyTax(uint48 _marketingTax, uint48 _revShareTax) external onlyOwner {
Taxes memory taxes;
taxes.marketingTax = _marketingTax;
taxes.revShareTax = _revShareTax;
taxes.totalTax = _marketingTax + _revShareTax;
require(taxes.totalTax <= 300, "Keep tax below 3%");
emit UpdatedBuyTax(taxes.totalTax);
buyTax = taxes;
}
function updateSellTax(uint48 _marketingTax, uint48 _revShareTax) external onlyOwner {
Taxes memory taxes;
taxes.marketingTax = _marketingTax;
taxes.revShareTax = _revShareTax;
taxes.totalTax = _marketingTax + _revShareTax;
require(taxes.totalTax <= 300, "Keep tax below 3%");
emit UpdatedSellTax(taxes.totalTax);
sellTax = taxes;
}
function enableTrading() external onlyOwner {
require(!tradingAllowed, "Trading already live");
tradingAllowed = true;
launchTime = block.timestamp;
}
function removeTransferDelay() external onlyOwner {
require(transferDelayEnabled, "Already disabled");
transferDelayEnabled = false;
}
function removeDynamicTax() external onlyOwner {
require(dynamicTaxOn, "Already disabled");
dynamicTaxOn = false;
}
function removeLimits() external onlyOwner {
limited = false;
transferDelayEnabled = false;
TxLimits memory _txLimits;
uint256 supply = totalSupply();
_txLimits.transactionLimit = uint128(supply);
_txLimits.walletLimit = uint128(supply);
txLimits = _txLimits;
emit RemovedLimits();
}
function airdropToWallets(address[] calldata wallets, uint256[] calldata amountsInWei) external onlyOwner {
require(wallets.length == amountsInWei.length, "arrays length mismatch");
require(!tradingAllowed, "Cannot airdrop after trading enabled");
address wallet;
uint256 amount;
for(uint256 i = 0; i < wallets.length; i++){
wallet = wallets[i];
amount = amountsInWei[i];
super._transfer(msg.sender, wallet, amountsInWei[i]);
dividendTracker.setBalance(payable(wallet), amount);
}
}
function rescueTokens(address _token, address _to) external onlyOwner {
require(_token != address(0), "_token address cannot be 0");
require(_token != address(this), "_token address cannot be native token");
uint256 _contractBalance = IERC20(_token).balanceOf(address(this));
SafeERC20.safeTransfer(IERC20(_token),_to, _contractBalance);
}
function updateMarketingAddress(address _address) external onlyOwner {
require(_address != address(0), "zero address");
marketingAddress = _address;
}
function setInternalTaxes() internal {
Taxes memory newBuyTax = buyTax;
Taxes memory newSellTax = sellTax;
uint256 currentTime = block.timestamp;
uint256 timeSinceLaunch = currentTime - launchTime;
if(timeSinceLaunch >= 45 minutes){
dynamicTaxOn = false;
newBuyTax.marketingTax = 150;
newBuyTax.revShareTax = 150;
newBuyTax.totalTax = 300;
newSellTax.marketingTax = 150;
newSellTax.revShareTax = 150;
newSellTax.totalTax = 300;
} else if (timeSinceLaunch >= 30 minutes){
newBuyTax.marketingTax = 500;
newBuyTax.revShareTax = 0;
newBuyTax.totalTax = 500;
newSellTax.marketingTax = 1000;
newSellTax.revShareTax = 0;
newSellTax.totalTax = 1000;
} else if (timeSinceLaunch >= 15 minutes){
newBuyTax.marketingTax = 700;
newBuyTax.revShareTax = 0;
newBuyTax.totalTax = 700;
newSellTax.marketingTax = 1500;
newSellTax.totalTax = 1500;
}
if(buyTax.totalTax != newBuyTax.totalTax){
buyTax = newBuyTax;
}
if(sellTax.totalTax != newSellTax.totalTax){
sellTax = newSellTax;
}
}
receive() payable external {}
function claim() external {
dividendTracker.processAccount(payable(msg.sender), false);
}
function getTotalDividendsDistributed() external view returns (uint256) {
return dividendTracker.totalDividendsDistributed();
}
function withdrawableDividendOf(address account) public view returns(uint256) {
return dividendTracker.withdrawableDividendOf(account);
}
function dividendTokenBalanceOf(address account) public view returns (uint256) {
return dividendTracker.holderBalance(account);
}
function getAccountDividendsInfo(address account)
external view returns (
address,
uint256,
uint256,
uint256) {
return dividendTracker.getAccount(account);
}
function getNumberOfDividends() external view returns(uint256) {
return dividendTracker.totalBalance();
}
function excludeFromDividends(address _wallet) external onlyOwner {
dividendTracker.excludeFromDividends(_wallet);
}
function includeInDividends(address _wallet) external onlyOwner {
dividendTracker.includeInDividends(_wallet);
}
function compound(uint256 minOutput) external {
uint256 amountEthForCompound = dividendTracker.withdrawDividendOfUserForCompound(payable(msg.sender));
if(amountEthForCompound > 0){
buyBackTokens(amountEthForCompound, minOutput, msg.sender);
} else {
revert("No rewards");
}
}
function buyBackTokens(uint256 ethAmountInWei, uint256 minOut, address to) internal {
address[] memory path = new address[](2);
path[0] = dexRouter.WETH();
path[1] = address(this);
dexRouter.swapExactETHForTokensSupportingFeeOnTransferTokens{value: ethAmountInWei}(
minOut,
path,
address(to),
block.timestamp
);
}
function getExpectedCompoundOutputByEthAmount(uint256 rewardAmount) external view returns(uint256) {
address[] memory path = new address[](2);
path[0] = dexRouter.WETH();
path[1] = address(this);
uint256[] memory amounts = dexRouter.getAmountsOut(rewardAmount, path);
return amounts[1] - (amounts[1] * (buyTax.totalTax + 50) / FEE_DIVISOR);
}
function getExpectedCompoundOutputByWallet(address wallet) external view returns(uint256) {
uint256 rewardAmount = withdrawableDividendOf(wallet);
address[] memory path = new address[](2);
path[0] = dexRouter.WETH();
path[1] = address(this);
uint256[] memory amounts = dexRouter.getAmountsOut(rewardAmount, path);
return amounts[1] - (amounts[1] * (buyTax.totalTax + 50) / FEE_DIVISOR);
}
function addLp(address _to) external onlyOwner payable {
require(address(this).balance > 0 && balanceOf(address(this)) > 0);
WETH.deposit{value: address(this).balance}();
super._transfer(address(this), address(lpPair), balanceOf(address(this)));
IERC20(address(WETH)).transfer(address(lpPair), IERC20(address(WETH)).balanceOf(address(this)));
ILpPair(lpPair).mint(_to);
}
}