文件 1 的 1:DividendTracker.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;
}
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));
}
}
contract NexusPro is ERC20, Ownable {
mapping (address => bool) public exemptFromFees;
mapping (address => bool) public exemptFromLimits;
bool public tradingAllowed;
mapping (address => bool) public isAMMPair;
address public marketingAddress;
address public devAddress;
DividendTracker public dividendTracker;
Taxes public buyTax;
Taxes public sellTax;
TokensForTax public tokensForTax;
mapping(address => uint256) private _holderLastTransferBlock;
bool public antiMevEnabled = true;
bool public limited = true;
uint256 public swapTokensAtAmt;
address public lpPair;
IDexRouter public dexRouter;
address public immutable WETH;
TxLimits public txLimits;
uint64 public constant FEE_DIVISOR = 10000;
struct TxLimits {
uint128 transactionLimit;
uint128 walletLimit;
}
struct Taxes {
uint48 marketingTax;
uint48 devTax;
uint48 liquidityTax;
uint48 revShareTax;
uint48 totalTax;
}
struct TokensForTax {
uint64 tokensForMarketing;
uint64 tokensForLiquidity;
uint64 tokensForDev;
uint64 tokensForRevShare;
bool gasSaver;
}
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("Nexus Pro", "NEXUS")
{
_mint(msg.sender, 100_000_000 * 1e18);
address _v2Router;
if(block.chainid == 1){
_v2Router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
} else if(block.chainid == 5){
_v2Router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
} else {
revert("Chain not configured");
}
dividendTracker = new DividendTracker();
dexRouter = IDexRouter(_v2Router);
txLimits.transactionLimit = uint128(totalSupply() * 20 / 1000);
txLimits.walletLimit = uint128(totalSupply() * 2 / 100);
swapTokensAtAmt = totalSupply() * 25 / 100000;
marketingAddress = 0x2Ad8787f1EdBe8A0F81F130Ce7846390E2a7715E;
devAddress = 0xBAE8B6b5D60BC1E1e4d10144149dA1458B7460DD;
buyTax.marketingTax = 600;
buyTax.liquidityTax = 300;
buyTax.devTax = 300;
buyTax.revShareTax = 300;
buyTax.totalTax = buyTax.marketingTax + buyTax.liquidityTax + buyTax.devTax + buyTax.revShareTax;
sellTax.marketingTax = 600;
sellTax.liquidityTax = 300;
sellTax.devTax = 300;
sellTax.revShareTax = 300;
sellTax.totalTax = sellTax.marketingTax + sellTax.liquidityTax + sellTax.devTax + buyTax.revShareTax + sellTax.revShareTax;
tokensForTax.gasSaver = true;
WETH = dexRouter.WETH();
lpPair = IDexFactory(dexRouter.factory()).createPair(address(this), 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));
_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 (antiMevEnabled){
if(isAMMPair[to]){
require(_holderLastTransferBlock[from] < block.number, "Anti MEV");
} else {
_holderLastTransferBlock[to] = block.number;
_holderLastTransferBlock[tx.origin] = block.number;
}
}
}
function handleTax(address from, address to, uint256 amount) internal returns (uint256){
if(balanceOf(address(this)) >= swapTokensAtAmt && !isAMMPair[from]) {
convertTaxes();
}
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.tokensForLiquidity += uint64(tax * taxes.liquidityTax / taxes.totalTax / 1e9);
tokensForTaxUpdate.tokensForMarketing += uint64(tax * taxes.marketingTax / taxes.totalTax / 1e9);
tokensForTaxUpdate.tokensForDev += uint64(tax * taxes.devTax / 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] = 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.tokensForLiquidity + tokensForTaxMem.tokensForMarketing + tokensForTaxMem.tokensForDev + tokensForTaxMem.tokensForRevShare;
if(contractBalance == 0 || totalTokensToSwap == 0) {return;}
if(contractBalance > swapTokensAtAmt * 20){
contractBalance = swapTokensAtAmt * 20;
}
if(tokensForTaxMem.tokensForLiquidity > 0){
uint256 liquidityTokens = contractBalance * tokensForTaxMem.tokensForLiquidity / totalTokensToSwap;
super._transfer(address(this), lpPair, liquidityTokens);
try ILpPair(lpPair).sync(){} catch {}
contractBalance -= liquidityTokens;
totalTokensToSwap -= tokensForTaxMem.tokensForLiquidity;
}
if(contractBalance > 0){
swapTokensForETH(contractBalance);
uint256 ethBalance = address(this).balance;
bool success;
if(tokensForTaxMem.tokensForDev > 0){
(success,) = devAddress.call{value: ethBalance * tokensForTaxMem.tokensForDev / totalTokensToSwap}("");
}
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.tokensForLiquidity = 0;
tokensForTaxMem.tokensForMarketing = 0;
tokensForTaxMem.tokensForDev = 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 / 1000)/(10**decimals()), "Too low");
txLimits.transactionLimit = uint128(newNumInTokens * (10**decimals()));
emit UpdatedTransactionLimit(txLimits.transactionLimit);
}
function updateWalletLimit(uint128 newNumInTokens) external onlyOwner {
require(newNumInTokens >= (totalSupply() * 1 / 1000)/(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 _liquidityTax, uint48 _devTax, uint48 _revShareTax) external onlyOwner {
Taxes memory taxes;
taxes.marketingTax = _marketingTax;
taxes.liquidityTax = _liquidityTax;
taxes.devTax = _devTax;
taxes.revShareTax = _revShareTax;
taxes.totalTax = _marketingTax + _liquidityTax + _devTax + _revShareTax;
require(taxes.totalTax <= 1000, "Keep tax below 10%");
emit UpdatedBuyTax(taxes.totalTax);
buyTax = taxes;
}
function updateSellTax(uint48 _marketingTax, uint48 _liquidityTax, uint48 _devTax, uint48 _revShareTax) external onlyOwner {
Taxes memory taxes;
taxes.marketingTax = _marketingTax;
taxes.liquidityTax = _liquidityTax;
taxes.devTax = _devTax;
taxes.revShareTax = _revShareTax;
taxes.totalTax = _marketingTax + _liquidityTax + _devTax + _revShareTax;
require(taxes.totalTax <= 1000, "Keep tax below 10%");
emit UpdatedSellTax(taxes.totalTax);
sellTax = taxes;
}
function enableTrading() external onlyOwner {
require(!tradingAllowed, "Trading already live");
tradingAllowed = true;
}
function removeLimits() external onlyOwner {
limited = false;
TxLimits memory _txLimits;
uint256 supply = totalSupply();
_txLimits.transactionLimit = uint128(supply);
_txLimits.walletLimit = uint128(supply);
txLimits = _txLimits;
emit RemovedLimits();
}
function updateMevBlockerEnabled(bool _enabled) external onlyOwner {
antiMevEnabled = _enabled;
}
function airdropToWallets(address[] calldata wallets, uint256[] calldata amountsInWei) external onlyOwner {
require(wallets.length == amountsInWei.length, "arrays length mismatch");
for(uint256 i = 0; i < wallets.length; i++){
super._transfer(msg.sender, wallets[i], amountsInWei[i]);
}
}
function rescueTokens(address _token, address _to) external onlyOwner {
require(_token != address(0), "_token address cannot be 0");
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 updateDevAddress(address _address) external onlyOwner {
require(_address != address(0), "zero address");
devAddress = _address;
}
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);
}
}