Contract Source Code:
File 1 of 1 : Baby$DIE
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
error Unauthorized();
error InsufficientBalance();
error NonContractCall();
error NeedLiquidity();
error MaxTaxExceeded(uint8 _MAX_TAX);
error BlacklistTimerExceeded();
error AlreadyBlacklisted();
error AlreadyUnblacklisted();
error AlreadyMaxTier();
error AlreadyBaseTier();
error MaxBuyExceeded(uint256 _maxBuy);
error MaxSellExceeded(uint256 _maxSell);
error MaxBalanceExceeded(uint256 _maxBalance);
error UserBlacklisted();
error LiquidityLocked(uint256 unlockInSeconds);
error InvalidInput();
interface IERC20 {
function totalSupply() external view returns (uint256);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function getOwner() external view returns (address);
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 IUniSwapERC20 {
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event Transfer(address indexed from, address indexed to, uint256 value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint256);
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
interface IUniSwapFactory {
event PairCreated(
address indexed token0,
address indexed token1,
address pair,
uint256
);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function getPair(address tokenA, address tokenB)
external
view
returns (address pair);
function allPairs(uint256) external view returns (address pair);
function allPairsLength() external view returns (uint256);
function createPair(address tokenA, address tokenB)
external
returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
}
interface IUniSwapRouter01 {
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
)
external
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (
uint256 amountToken,
uint256 amountETH,
uint256 liquidity
);
function removeLiquidity(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB);
function removeLiquidityETH(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
) external returns (uint256 amountToken, uint256 amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 amountA, uint256 amountB);
function removeLiquidityETHWithPermit(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 amountToken, uint256 amountETH);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapTokensForExactTokens(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactETHForTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function swapTokensForExactETH(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapETHForExactTokens(
uint256 amountOut,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function factory() external pure returns (address);
function WETH() external pure returns (address);
function quote(
uint256 amountA,
uint256 reserveA,
uint256 reserveB
) external pure returns (uint256 amountB);
function getamountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) external pure returns (uint256 amountOut);
function getamountIn(
uint256 amountOut,
uint256 reserveIn,
uint256 reserveOut
) external pure returns (uint256 amountIn);
function getamountsOut(uint256 amountIn, address[] calldata path)
external
view
returns (uint256[] memory amounts);
function getamountsIn(uint256 amountOut, address[] calldata path)
external
view
returns (uint256[] memory amounts);
}
interface IUniSwapRouter02 is IUniSwapRouter01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
) external returns (uint256 amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
}
abstract contract Ownable {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor() {
address msgSender = msg.sender;
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
function _onlyOwner() private view {
if (owner() != msg.sender) revert Unauthorized();
}
modifier onlyOwner() {
_onlyOwner();
_;
}
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
library Address {
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) revert InsufficientBalance();
(bool success, ) = recipient.call{value: amount}("");
require(success);
}
function functionCall(address target, bytes memory data)
internal
returns (bytes memory)
{
return functionCall(target, data, "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) {
if (address(this).balance < value) revert InsufficientBalance();
if (!isContract(target)) revert NonContractCall();
(bool success, bytes memory returndata) = target.call{value: value}(
data
);
return _verifyCallResult(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) {
if (!isContract(target)) revert NonContractCall();
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(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) {
if (!isContract(target)) revert NonContractCall();
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) private pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
bytes32 lastvalue = set._values[lastIndex];
set._values[toDeleteIndex] = lastvalue;
set._indexes[lastvalue] = valueIndex;
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value)
private
view
returns (bool)
{
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index)
private
view
returns (bytes32)
{
require(
set._values.length > index,
"EnumerableSet: index out of bounds"
);
return set._values[index];
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value)
internal
returns (bool)
{
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value)
internal
returns (bool)
{
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value)
internal
view
returns (bool)
{
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index)
internal
view
returns (bytes32)
{
return _at(set._inner, index);
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value)
internal
returns (bool)
{
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value)
internal
returns (bool)
{
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value)
internal
view
returns (bool)
{
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index)
internal
view
returns (address)
{
return address(uint160(uint256(_at(set._inner, index))));
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value)
internal
returns (bool)
{
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value)
internal
view
returns (bool)
{
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index)
internal
view
returns (uint256)
{
return uint256(_at(set._inner, index));
}
}
contract Baby$DIE is IERC20, Ownable {
using Address for address;
using EnumerableSet for EnumerableSet.AddressSet;
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
mapping(address => bool) public isBlacklisted;
mapping(address => bool) public isWhitelisted;
mapping(address => bool) public taxExempt;
mapping(address => bool) public limitExempt;
mapping(address => bool) public tier2;
mapping(address => bool) public tier3;
// add mapping store all holder information
uint256 public totalTokenHolderHistory = 0;
mapping (uint256=> address ) public tokenHolderHistory;
mapping (address=> bool ) public addedToTokenHolderHistory;
EnumerableSet.AddressSet private _excluded;
EnumerableSet.AddressSet private _excludedFromStaking;
string private _name = "Baby $DIE";
string private _symbol = "BDIE";
uint256 private constant INITIAL_SUPPLY = 1_000_000_000 * 10**TOKEN_DECIMALS;
uint256 private _circulatingSupply;
uint8 private constant TOKEN_DECIMALS = 18;
uint8 public constant MAX_TAX = 10; //Team can never set tax higher than this value
address private constant BURN_ADDRESS =
0x000000000000000000000000000000000000dEaD;
struct TaxRatios {
uint8 burn;
uint8 buyback;
uint8 Team;
uint8 liquidity;
uint8 Events;
uint8 Marketing;
uint8 rewards;
}
struct TaxWallets {
address Team;
address Events;
address Marketing;
}
struct MaxLimits {
uint256 maxWallet;
uint256 maxSell;
uint256 maxBuy;
}
struct LimitRatios {
uint16 wallet;
uint16 sell;
uint16 buy;
uint16 divisor;
}
struct TierTaxes {
uint8 first;
uint8 second;
uint8 third;
}
TierTaxes public _buyTaxes = TierTaxes({first: 5, second: 5, third: 5});
TierTaxes public _sellTaxes = TierTaxes({first: 5, second: 5, third: 5});
TaxRatios public _taxRatios =
TaxRatios({
burn: 0,
buyback: 0,
Team: 0,
liquidity: 40,
Events: 0,
Marketing: 60,
rewards: 0
//@Team. These are ratios and the divisor will be set automatically
});
TaxWallets public _taxWallet =
TaxWallets({
Team: 0x0d7D4e9Bbe63c1FE7888EF65A1Bd4F34163857A8,
Events: 0x0d7D4e9Bbe63c1FE7888EF65A1Bd4F34163857A8,
Marketing: 0x0d7D4e9Bbe63c1FE7888EF65A1Bd4F34163857A8
});
MaxLimits public _limits;
LimitRatios public _limitRatios =
LimitRatios({wallet: 4, sell: 4, buy: 4, divisor: 200});
uint8 private totalTaxRatio;
uint8 private totalSwapRatio;
uint8 private distributeRatio;
//launchTransferTax -- used to stop transfer of whitelisted tokens
uint256 launchTransferTax = 99;
//these values must add up to 100
uint8 private mainRewardSplit = 100;
uint8 private miscRewardSplit = 0;
uint256 private _liquidityUnlockTime;
//Antibot variables
bool public isLaunched;
uint256 private launchBlock;
uint256 private launchTime;
uint256 private blacklistWindow = 24 hours;
uint8 private constant BLACKLIST_BLOCKS = 0; //number of blocks that will be included in auto blacklist
uint8 private snipersRekt; //variable to track number of snipers auto blacklisted
bool private blacklistEnabled = true; //blacklist can be enabled/disabled in case something goes wrong
bool private revertSameBlock = true; //block same block buys
bool private dynamicBurn = false;
//dynamicBurn = true will burn all extra sell tax from dynamicSells
//dynamicBurn = false will divert all extra sell tax to swaps
bool private dynamicSellsEnabled = false;
//dynamic sells will increase tax based on price impact
//any sells over 1% price impact will incur extra sell tax
//max extra sell tax is 10% when price impact >= 10%
bool private dynamicLimits = false;
//dynamicLimits = true will change MaxLimits based on circulating supply rather than total supply
bool private dynamicLiqEnabled = false;
//dynamicLiqEnabled = true will stop autoLP if targetLiquidityRatio is met
//tax meant for liquidity will be redirected to other swap taxes in this case
uint16 private targetLiquidityRatio = 20; //target liquidity out of 100
uint16 public swapThreshold = 25; //threshold that contract will swap. out of 1000
bool public manualSwap;
//change this address to desired reward token. miscReward is custom chosen by holder
address public mainReward = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address public _uniswapPairAddress;
IUniSwapRouter02 private _uniswapRouter;
address public UniSwapRouter;
///////////////////////////// Events /////////////////////////////////////////
event AdjustedDynamicSettings(
bool burn,
bool limits,
bool liquidity,
bool sells
);
event AccountExcluded(address account);
event ChangeMainReward(address newMainReward);
event ClaimToken(uint256 amount, address token, address recipient);
event ClaimETH(address from, address to, uint256 amount);
event EnableBlacklist(bool enabled);
event EnableManualSwap(bool enabled);
event ExcludedAccountFromFees(address account, bool exclude);
event ExcludeFromStaking(address account, bool excluded);
event ExtendLiquidityLock(uint256 extendedLockTime);
event UpdateTaxes(uint8 buyTax, uint8 sellTax, uint8 transferTax);
event RatiosChanged(
uint8 newBurn,
uint8 newBuyback,
uint8 newTeam,
uint8 newLiquidity,
uint8 newEvents,
uint8 newMarketing,
uint8 newRewards
);
event UpdateTeamWallet(address newTeamWallet);
event UpdateEventsWallet(address newEventsWallet);
event UpdateMarketingWallet(address newMarketingWallet);
event UpdateRewardSplit(uint8 newMainSplit, uint8 newMiscSplit);
event UpdateSwapThreshold(uint16 newThreshold);
event UpdateTargetLiquidity(uint16 target);
///////////////////////////// MODIFIERS /////////////////////////////////////////
modifier authorized() {
_isAuthorized();
_;
}
modifier lockTheSwap() {
_isSwappingContractModifier = true;
_;
_isSwappingContractModifier = false;
}
///////////////////////////// CONSTRUCTOR /////////////////////////////////////////
constructor() {
if (block.chainid == 1) {
UniSwapRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
} else if (block.chainid == 5) {
UniSwapRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
} else revert();
_uniswapRouter = IUniSwapRouter02(UniSwapRouter);
_uniswapPairAddress = IUniSwapFactory(_uniswapRouter.factory())
.createPair(address(this), _uniswapRouter.WETH());
_addToken(msg.sender, INITIAL_SUPPLY);
emit Transfer(address(0), msg.sender, INITIAL_SUPPLY);
_allowances[address(this)][address(_uniswapRouter)] = type(uint256).max;
//setup ratio divisors based on Team's chosen ratios
totalTaxRatio =
_taxRatios.burn +
_taxRatios.buyback +
_taxRatios.Team +
_taxRatios.liquidity +
_taxRatios.Events +
_taxRatios.Marketing +
_taxRatios.rewards;
totalSwapRatio = totalTaxRatio - _taxRatios.burn;
distributeRatio = totalSwapRatio - _taxRatios.liquidity;
//circulating supply begins as initial supply
_circulatingSupply = INITIAL_SUPPLY;
//setup _limits
_limits = MaxLimits({
maxWallet: (INITIAL_SUPPLY * _limitRatios.wallet) /
_limitRatios.divisor,
maxSell: (INITIAL_SUPPLY * _limitRatios.sell) /
_limitRatios.divisor,
maxBuy: (INITIAL_SUPPLY * _limitRatios.buy) / _limitRatios.divisor
});
_excluded.add(msg.sender);
_excluded.add(_taxWallet.Marketing);
_excluded.add(_taxWallet.Team);
_excluded.add(_taxWallet.Events);
_excluded.add(address(this));
_excluded.add(BURN_ADDRESS);
_excludedFromStaking.add(address(this));
_excludedFromStaking.add(BURN_ADDRESS);
_excludedFromStaking.add(address(_uniswapRouter));
_excludedFromStaking.add(_uniswapPairAddress);
_approve(address(this), address(_uniswapRouter), type(uint256).max);
}
receive() external payable {}
//allows Team to change token name and symbol.
function updateTokenDetails(string memory newName, string memory newSymbol)
external
authorized
{
_name = newName;
_symbol = newSymbol;
}
function decimals() external pure override returns (uint8) {
return TOKEN_DECIMALS;
}
function getOwner() external view override returns (address) {
return owner();
}
function name() external view override returns (string memory) {
return _name;
}
function symbol() external view override returns (string memory) {
return _symbol;
}
function totalSupply() external view override returns (uint256) {
return _circulatingSupply;
}
function _isAuthorized() private view {
if (!_authorized(msg.sender)) revert Unauthorized();
}
function _authorized(address addr) private view returns (bool) {
return
addr == owner() ||
addr == _taxWallet.Marketing ||
addr == _taxWallet.Team ||
addr == _taxWallet.Events;
}
function allowance(address _owner, address spender)
external
view
override
returns (uint256)
{
return _allowances[_owner][spender];
}
function approve(address spender, uint256 amount)
external
override
returns (bool)
{
_approve(msg.sender, spender, amount);
return true;
}
function _approve(
address owner,
address spender,
uint256 amount
) private {
require(owner != address(0), "Approve from zero");
require(spender != address(0), "Approve to zero");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function balanceOf(address account)
external
view
override
returns (uint256)
{
return _balances[account];
}
function decreaseAllowance(address spender, uint256 subtractedValue)
external
returns (bool)
{
uint256 currentAllowance = _allowances[msg.sender][spender];
require(currentAllowance >= subtractedValue, "<0 allowance");
_approve(msg.sender, spender, currentAllowance - subtractedValue);
return true;
}
function increaseAllowance(address spender, uint256 addedValue)
external
returns (bool)
{
_approve(
msg.sender,
spender,
_allowances[msg.sender][spender] + addedValue
);
return true;
}
// Method to log holders to looping of distribution
function addAddressToHolderHistoryList(address _account) private {
if(!addedToTokenHolderHistory[_account]){
tokenHolderHistory[totalTokenHolderHistory] = _account;
addedToTokenHolderHistory[_account] = true;
totalTokenHolderHistory++;
}
}
function transfer(address recipient, uint256 amount)
external
override
returns (bool)
{
_transfer(msg.sender, recipient, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) external override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][msg.sender];
require(currentAllowance >= amount, "Transfer > allowance");
_approve(sender, msg.sender, currentAllowance - amount);
return true;
}
///// FUNCTIONS CALLABLE BY ANYONE /////
//Claims reward set by Team
function ClaimMainReward() external {
if (mainReward == _uniswapRouter.WETH()) {
claimETHTo(
msg.sender,
msg.sender,
getStakeBalance(msg.sender, true),
true
);
} else claimToken(msg.sender, mainReward, 0, true);
}
//Claims reward chosen by holder. Differentiates between ETH and other ERC20 tokens
function ClaimMiscReward(address tokenAddress) external {
if (tokenAddress == _uniswapRouter.WETH()) {
claimETHTo(
msg.sender,
msg.sender,
getStakeBalance(msg.sender, false),
false
);
} else claimToken(msg.sender, tokenAddress, 0, false);
}
//Allows holders to include themselves back into staking if excluded
//ExcludeFromStaking function should be used for contracts(CEX, pair, address(this), etc.)
function IncludeMeToStaking() external {
includeToStaking(msg.sender);
emit ExcludeFromStaking(msg.sender, false);
}
///// AUTHORIZED FUNCTIONS /////
//Allows Team to change reward
function changeMainReward(address newReward) external onlyOwner {
mainReward = newReward;
emit ChangeMainReward(newReward);
}
//Manually perform a contract swap
function createLPandETH(uint16 permilleOfUniSwap, bool ignoreLimits)
external
onlyOwner
{
_swapContractToken(permilleOfUniSwap, ignoreLimits);
}
//Toggle blacklist on and off
function enableBlacklist(bool enabled) external onlyOwner {
blacklistEnabled = enabled;
emit EnableBlacklist(enabled);
}
//Toggle dynamic features on and off
function dynamicSettings(
bool burn,
bool limits,
bool liquidity,
bool sells
) external onlyOwner {
dynamicBurn = burn;
dynamicLimits = limits;
dynamicLiqEnabled = liquidity;
dynamicSellsEnabled = sells;
emit AdjustedDynamicSettings(burn, limits, liquidity, sells);
}
//Mainly used for addresses such as CEX, presale, etc
function excludeAccountFromFees(address account, bool exclude)
external
onlyOwner
{
if (exclude == true) _excluded.add(account);
else _excluded.remove(account);
emit ExcludedAccountFromFees(account, exclude);
}
//Mainly used for addresses such as CEX, presale, etc
function setStakingExclusionStatus(address addr, bool exclude)
external
onlyOwner
{
if (exclude) excludeFromStaking(addr);
else includeToStaking(addr);
emit ExcludeFromStaking(addr, exclude);
}
//Toggle manual swap on and off
function enableManualSwap(bool enabled) external onlyOwner {
manualSwap = enabled;
emit EnableManualSwap(enabled);
}
function launch() external onlyOwner {
if (IERC20(_uniswapPairAddress).totalSupply() == 0)
revert NeedLiquidity();
isLaunched = true;
launchBlock = block.number;
launchTime = block.timestamp;
}
//Toggle whether multiple buys in a block from a single address can be performed
function sameBlockRevert(bool enabled) external onlyOwner {
revertSameBlock = enabled;
}
function addBlacklist(address addr) external authorized {
if (block.timestamp > (launchTime + blacklistWindow))
revert BlacklistTimerExceeded();
if (isBlacklisted[addr]) revert AlreadyBlacklisted();
isBlacklisted[addr] = true;
}
function removeBlacklist(address addr) external authorized {
if (!isBlacklisted[addr]) revert AlreadyUnblacklisted();
isBlacklisted[addr] = false;
}
function setTier1(address[] calldata addresses) external onlyOwner {
for (uint256 i = 0; i < addresses.length; ++i) {
tier2[addresses[i]] = false;
tier3[addresses[i]] = false;
}
}
function setTier2(address[] calldata addresses) external onlyOwner {
for (uint256 i = 0; i < addresses.length; ++i) {
tier2[addresses[i]] = true;
tier3[addresses[i]] = false;
}
}
function setTier3(address[] calldata addresses) external onlyOwner {
for (uint256 i = 0; i < addresses.length; ++i) {
tier2[addresses[i]] = false;
tier3[addresses[i]] = true;
}
}
//indepedently set whether wallet is exempt from taxes
function setTaxExemptionStatus(address account, bool exempt)
external
onlyOwner
{
taxExempt[account] = exempt;
}
//independtly set whether wallet is exempt from limits
function setLimitExemptionStatus(address account, bool exempt)
external
onlyOwner
{
limitExempt[account] = exempt;
}
function setWhitelistStatus(address[] calldata addresses, bool status)
external
onlyOwner
{
for (uint256 i = 0; i < addresses.length; ++i) {
isWhitelisted[addresses[i]] = status;
}
}
//Performs a buyback and automatically burns tokens
function triggerBuyback(uint256 amount) external authorized {
buybackToken(amount, address(this));
}
//Update limit ratios. ofCurrentSupply = true will set max wallet based on current supply. False will use initial supply
function updateLimits(
uint16 newMaxWalletRatio,
uint16 newMaxSellRatio,
uint16 newMaxBuyRatio,
uint16 newDivisor,
bool ofCurrentSupply
) external onlyOwner {
uint256 supply = INITIAL_SUPPLY;
if (ofCurrentSupply) supply = _circulatingSupply;
uint256 minLimit = supply / 1000;
uint256 newMaxWallet = (supply * newMaxWalletRatio) / newDivisor;
uint256 newMaxSell = (supply * newMaxSellRatio) / newDivisor;
uint256 newMaxBuy = (supply * newMaxBuyRatio) / newDivisor;
//Team can never set sells below 0.1% of circulating/initial supply
if (newMaxWallet < minLimit || newMaxSell < minLimit)
revert InvalidInput();
_limits = MaxLimits(newMaxWallet, newMaxSell, newMaxBuy);
_limitRatios = LimitRatios(
newMaxWalletRatio,
newMaxSellRatio,
newMaxBuyRatio,
newDivisor
);
}
//update launch tax ratios
function updateLaunchTransferTax(
uint8 newLaunchTransferTax
) external onlyOwner {
require(launchTransferTax > 0, "Launch Transfer Tax has been removed and cannot be re-enabled");
launchTransferTax = newLaunchTransferTax;
}
//update tax ratios
function updateRatios(
uint8 newBurn,
uint8 newBuyback,
uint8 newTeam,
uint8 newLiquidity,
uint8 newEvents,
uint8 newMarketing,
uint8 newRewards
) external onlyOwner {
_taxRatios = TaxRatios(
newBurn,
newBuyback,
newTeam,
newLiquidity,
newEvents,
newMarketing,
newRewards
);
totalTaxRatio =
newBurn +
newBuyback +
newTeam +
newLiquidity +
newEvents +
newMarketing +
newRewards;
totalSwapRatio = totalTaxRatio - newBurn;
distributeRatio = totalSwapRatio - newLiquidity;
emit RatiosChanged(
newBurn,
newBuyback,
newTeam,
newLiquidity,
newEvents,
newMarketing,
newRewards
);
}
//update allocation of mainReward and miscReward
function updateRewardSplit(uint8 mainSplit, uint8 miscSplit)
external
onlyOwner
{
uint8 totalSplit = mainSplit + miscSplit;
if (totalSplit != 100) revert InvalidInput();
mainRewardSplit = mainSplit;
miscRewardSplit = miscSplit;
emit UpdateRewardSplit(mainSplit, miscSplit);
}
//update threshold that triggers contract swaps
function updateSwapThreshold(uint16 threshold) external onlyOwner {
if (threshold < 0 || threshold > 50) revert InvalidInput();
swapThreshold = threshold;
emit UpdateSwapThreshold(threshold);
}
//targetLiquidity is out of 100
function updateTargetLiquidity(uint16 target) external onlyOwner {
if (target > 100) revert InvalidInput();
targetLiquidityRatio = target;
emit UpdateTargetLiquidity(target);
}
function updateBuyTaxes(
uint8 first,
uint8 second,
uint8 third
) external onlyOwner {
if (first > MAX_TAX || second > MAX_TAX || third > MAX_TAX)
revert MaxTaxExceeded(MAX_TAX);
_buyTaxes = TierTaxes(first, second, third);
}
function updateSellTaxes(
uint8 first,
uint8 second,
uint8 third
) external onlyOwner {
if (first > MAX_TAX || second > MAX_TAX || third > MAX_TAX)
revert MaxTaxExceeded(MAX_TAX);
_sellTaxes = TierTaxes(first, second, third);
}
function withdrawTeam() external authorized {
uint256 remaining = address(this).balance -
TeamBalance -
EventsBalance -
MarketingBalance -
buybackBalance -
getTotalUnclaimed();
bool lostBalance = remaining > 0;
uint256 amount = lostBalance ? TeamBalance + remaining : TeamBalance;
TeamBalance = 0;
_sendETH(_taxWallet.Team, amount);
}
function withdrawEvents() external authorized {
uint256 amount = EventsBalance;
EventsBalance = 0;
_sendETH(_taxWallet.Events, amount);
}
function withdrawMarketing() external authorized {
uint256 amount = MarketingBalance;
MarketingBalance = 0;
_sendETH(_taxWallet.Marketing, amount);
}
//liquidity can only be extended
function lockLiquidityTokens(uint256 lockTimeInSeconds)
external
authorized
{
setUnlockTime(lockTimeInSeconds + block.timestamp);
emit ExtendLiquidityLock(lockTimeInSeconds);
}
//recovers stuck ETH to make sure it isnt burnt/lost
//only callablewhen liquidity is unlocked
function recoverETH() external authorized {
if (block.timestamp < _liquidityUnlockTime)
revert LiquidityLocked(_liquidityUnlockTime - block.timestamp);
_liquidityUnlockTime = block.timestamp;
_sendETH(msg.sender, address(this).balance);
}
//Can only be used to recover miscellaneous tokens accidentally sent to contract
//Can't pull liquidity or native token using this function
function recoverMiscToken(address tokenAddress) external authorized {
if (
tokenAddress == _uniswapPairAddress || tokenAddress == address(this)
) revert InvalidInput();
IERC20 token = IERC20(tokenAddress);
token.transfer(msg.sender, token.balanceOf(address(this)));
}
//Impossible to release LP unless LP lock time is zero
function releaseLP() external authorized {
if (block.timestamp < _liquidityUnlockTime)
revert LiquidityLocked(_liquidityUnlockTime - block.timestamp);
IUniSwapERC20 liquidityToken = IUniSwapERC20(_uniswapPairAddress);
uint256 amount = liquidityToken.balanceOf(address(this));
liquidityToken.transfer(msg.sender, amount);
}
//Impossible to remove LP unless lock time is zero
function removeLP() external authorized {
if (block.timestamp < _liquidityUnlockTime)
revert LiquidityLocked(_liquidityUnlockTime - block.timestamp);
_liquidityUnlockTime = block.timestamp;
IUniSwapERC20 liquidityToken = IUniSwapERC20(_uniswapPairAddress);
uint256 amount = liquidityToken.balanceOf(address(this));
liquidityToken.approve(address(_uniswapRouter), amount);
_uniswapRouter.removeLiquidityETHSupportingFeeOnTransferTokens(
address(this),
amount,
0,
0,
address(this),
block.timestamp
);
_sendETH(msg.sender, address(this).balance);
}
function setTeamWallet(address payable addr) external authorized {
address prevTeam = _taxWallet.Team;
_excluded.remove(prevTeam);
_taxWallet.Team = addr;
_excluded.add(_taxWallet.Team);
emit UpdateTeamWallet(addr);
}
function setEventsWallet(address payable addr) external authorized {
address prevEvents = _taxWallet.Events;
_excluded.remove(prevEvents);
_taxWallet.Events = addr;
_excluded.add(_taxWallet.Events);
emit UpdateEventsWallet(addr);
}
function setMarketingWallet(address payable addr) external authorized {
address prevMarketing = _taxWallet.Marketing;
_excluded.remove(prevMarketing);
_taxWallet.Marketing = addr;
_excluded.add(_taxWallet.Marketing);
emit UpdateMarketingWallet(addr);
}
////// VIEW FUNCTIONS /////
function getBlacklistInfo()
external
view
returns (
uint256 _launchBlock,
uint8 _blacklistBlocks,
uint8 _snipersRekt,
bool _blacklistEnabled,
bool _revertSameBlock
)
{
return (
launchBlock,
BLACKLIST_BLOCKS,
snipersRekt,
blacklistEnabled,
revertSameBlock
);
}
function getDynamicInfo()
external
view
returns (
bool _dynamicBurn,
bool _dynamicLimits,
bool _dynamicLiquidity,
bool _dynamicSells,
uint16 _targetLiquidity
)
{
return (
dynamicBurn,
dynamicLimits,
dynamicLiqEnabled,
dynamicSellsEnabled,
targetLiquidityRatio
);
}
function getLiquidityRatio() public view returns (uint256) {
uint256 ratio = (100 * _balances[_uniswapPairAddress]) /
_circulatingSupply;
return ratio;
}
function getLiquidityUnlockInSeconds() external view returns (uint256) {
if (block.timestamp < _liquidityUnlockTime) {
return _liquidityUnlockTime - block.timestamp;
}
return 0;
}
function getMainBalance(address addr) external view returns (uint256) {
uint256 amount = getStakeBalance(addr, true);
return amount;
}
function getMiscBalance(address addr) external view returns (uint256) {
uint256 amount = getStakeBalance(addr, false);
return amount;
}
function getSupplyInfo()
external
view
returns (
uint256 initialSupply,
uint256 circulatingSupply,
uint256 burntTokens
)
{
uint256 tokensBurnt = INITIAL_SUPPLY - _circulatingSupply;
return (INITIAL_SUPPLY, _circulatingSupply, tokensBurnt);
}
function getTotalUnclaimed() public view returns (uint256) {
uint256 amount = totalRewards - totalPayouts;
return amount;
}
function getWithdrawBalances()
external
view
returns (
uint256 buyback,
uint256 Team,
uint256 Events,
uint256 Marketing
)
{
return (buybackBalance, TeamBalance, EventsBalance, MarketingBalance);
}
function isExcludedFromStaking(address addr) external view returns (bool) {
return _excludedFromStaking.contains(addr);
}
///////////////////////////// PRIVATE FUNCTIONS /////////////////////////////////////////
mapping(address => uint256) private alreadyPaidMain;
mapping(address => uint256) private toERCaidMain;
mapping(address => uint256) private alreadyPaidMisc;
mapping(address => uint256) private toERCaidMisc;
mapping(address => uint256) private tradeBlock;
mapping(address => uint256) public accountTotalClaimed;
uint256 private constant DISTRIBUTION_MULTI = 2**64;
uint256 private _totalShares = INITIAL_SUPPLY;
uint256 private buybackBalance;
uint256 private TeamBalance;
uint256 private EventsBalance;
uint256 private MarketingBalance;
uint256 private mainRewardShare;
uint256 private miscRewardShare;
uint256 public totalPayouts;
uint256 public totalRewards;
bool private _isSwappingContractModifier;
bool private _isWithdrawing;
bool private _isBurning;
function _addLiquidity(uint256 tokenamount, uint256 ETHAmount) private {
_approve(address(this), address(_uniswapRouter), tokenamount);
_uniswapRouter.addLiquidityETH{value: ETHAmount}(
address(this),
tokenamount,
0,
0,
address(this),
block.timestamp
);
}
function _addToken(address addr, uint256 amount) private {
uint256 newAmount = _balances[addr] + amount;
if (_excludedFromStaking.contains(addr)) {
_balances[addr] = newAmount;
return;
}
_totalShares += amount;
uint256 mainPayment = newStakeOf(addr, true);
uint256 miscPayment = newStakeOf(addr, false);
_balances[addr] = newAmount;
alreadyPaidMain[addr] = mainRewardShare * newAmount;
toERCaidMain[addr] += mainPayment;
alreadyPaidMisc[addr] = miscRewardShare * newAmount;
toERCaidMisc[addr] += miscPayment;
_balances[addr] = newAmount;
// add history to holder list
addAddressToHolderHistoryList(addr);
}
function _calculateTierTax(address addr, bool isBuy)
private
view
returns (uint8)
{
if (!tier2[addr] && !tier3[addr]) {
return isBuy ? _buyTaxes.first : _sellTaxes.first;
} else if (tier3[addr]) {
return isBuy ? _buyTaxes.third : _sellTaxes.third;
} else {
return isBuy ? _buyTaxes.second : _sellTaxes.second;
}
}
function _distributeStake(uint256 ETHAmount, bool newStakingReward)
private
{
uint256 MarketingSplit = (ETHAmount * _taxRatios.Marketing) /
distributeRatio;
uint256 TeamSplit = (ETHAmount * _taxRatios.Team) / distributeRatio;
uint256 buybackSplit = (ETHAmount * _taxRatios.buyback) /
distributeRatio;
uint256 stakingSplit = (ETHAmount * _taxRatios.rewards) /
distributeRatio;
uint256 EventsSplit = (ETHAmount * _taxRatios.Events) / distributeRatio;
uint256 mainAmount = (stakingSplit * mainRewardSplit) / 100;
uint256 miscAmount = (stakingSplit * miscRewardSplit) / 100;
MarketingBalance += MarketingSplit;
TeamBalance += TeamSplit;
buybackBalance += buybackSplit;
EventsBalance += EventsSplit;
if (stakingSplit > 0) {
if (newStakingReward) totalRewards += stakingSplit;
uint256 totalShares = getTotalShares();
if (totalShares == 0) MarketingBalance += stakingSplit;
else {
mainRewardShare += ((mainAmount * DISTRIBUTION_MULTI) /
totalShares);
miscRewardShare += ((miscAmount * DISTRIBUTION_MULTI) /
totalShares);
}
}
}
function _feelessTransfer(
address sender,
address recipient,
uint256 amount
) private {
if (_balances[sender] < amount) revert InsufficientBalance();
_removeToken(sender, amount);
_addToken(recipient, amount);
emit Transfer(sender, recipient, amount);
}
function _removeToken(address addr, uint256 amount) private {
uint256 newAmount = _balances[addr] - amount;
if (_excludedFromStaking.contains(addr)) {
_balances[addr] = newAmount;
return;
}
_totalShares -= amount;
uint256 mainPayment = newStakeOf(addr, true);
uint256 miscPayment = newStakeOf(addr, false);
_balances[addr] = newAmount;
alreadyPaidMain[addr] = mainRewardShare * newAmount;
toERCaidMain[addr] += mainPayment;
alreadyPaidMisc[addr] = miscRewardShare * newAmount;
toERCaidMisc[addr] += miscPayment;
}
function _sendETH(address account, uint256 amount) private {
(bool sent, ) = account.call{value: (amount)}("");
require(sent, "withdraw failed");
}
function _swapContractToken(uint16 permilleOfUniSwap, bool ignoreLimits)
private
lockTheSwap
{
require(permilleOfUniSwap <= 500);
if (totalSwapRatio == 0) return;
uint256 contractBalance = _balances[address(this)];
uint256 tokenToSwap = (_balances[_uniswapPairAddress] *
permilleOfUniSwap) / 1000;
if (tokenToSwap > _limits.maxSell && !ignoreLimits)
tokenToSwap = _limits.maxSell;
bool notEnoughToken = contractBalance < tokenToSwap;
if (notEnoughToken) {
if (ignoreLimits) tokenToSwap = contractBalance;
else return;
}
if (_allowances[address(this)][address(_uniswapRouter)] < tokenToSwap)
_approve(address(this), address(_uniswapRouter), type(uint256).max);
uint256 dynamicLiqRatio;
if (dynamicLiqEnabled && getLiquidityRatio() >= targetLiquidityRatio)
dynamicLiqRatio = 0;
else dynamicLiqRatio = _taxRatios.liquidity;
uint256 tokenForLiquidity = (tokenToSwap * dynamicLiqRatio) /
totalSwapRatio;
uint256 remainingToken = tokenToSwap - tokenForLiquidity;
uint256 liqToken = tokenForLiquidity / 2;
uint256 liqETHToken = tokenForLiquidity - liqToken;
uint256 swapToken = liqETHToken + remainingToken;
uint256 initialETHBalance = address(this).balance;
_swapTokenForETH(swapToken);
uint256 newETH = (address(this).balance - initialETHBalance);
uint256 liqETH = (newETH * liqETHToken) / swapToken;
if (liqToken > 0) _addLiquidity(liqToken, liqETH);
uint256 distributeETH = (address(this).balance -
initialETHBalance -liqETH
);
_distributeStake(distributeETH, true);
}
function _swapTokenForETH(uint256 amount) private {
_approve(address(this), address(_uniswapRouter), amount);
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = _uniswapRouter.WETH();
_uniswapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
amount,
0,
path,
address(this),
block.timestamp
);
}
function _taxedTransfer(
address sender,
address recipient,
uint256 amount,
bool isBuy,
bool isSell
) private {
if (_balances[sender] < amount) revert InsufficientBalance();
uint8 tax;
bool extraSellTax = false;
uint256 launchTransferTaxAmount;
if (isSell) {
if (blacklistEnabled) {
if (isBlacklisted[sender]) revert UserBlacklisted();
}
if (amount > _limits.maxSell && !limitExempt[sender])
revert MaxSellExceeded(_limits.maxSell);
tax = _calculateTierTax(sender, false);
if (dynamicSellsEnabled) extraSellTax = true;
} else if (isBuy) {
if (!isLaunched && !isWhitelisted[recipient]) {
isBlacklisted[recipient] = true;
}
if (launchBlock > 0) {
if (block.number - launchBlock < BLACKLIST_BLOCKS) {
isBlacklisted[recipient] = true;
++snipersRekt;
}
}
if (revertSameBlock) {
require(tradeBlock[recipient] != block.number);
tradeBlock[recipient] = block.number;
}
if (
(_balances[recipient] + amount) > _limits.maxWallet &&
!limitExempt[recipient]
) revert MaxBalanceExceeded(_limits.maxWallet);
if (amount > _limits.maxBuy && !limitExempt[recipient])
revert MaxBuyExceeded(_limits.maxBuy);
tax = _calculateTierTax(recipient, true);
} else {
if (blacklistEnabled) {
if (isBlacklisted[sender]) revert UserBlacklisted();
}
if (amount <= 10**(TOKEN_DECIMALS)) {
//transfer less than 1 token to ClaimETH
if (mainReward == _uniswapRouter.WETH())
claimETHTo(
msg.sender,
msg.sender,
getStakeBalance(msg.sender, true),
true
);
else claimToken(msg.sender, mainReward, 0, true);
return;
}
if (
(_balances[recipient] + amount) > _limits.maxWallet &&
!limitExempt[recipient]
) revert MaxBalanceExceeded(_limits.maxWallet);
// on transfer during launch apply tax
if (launchTransferTax > 0) {
launchTransferTaxAmount = (amount * launchTransferTax) / 100;
}
}
if (
(sender != _uniswapPairAddress) &&
(!manualSwap) &&
(!_isSwappingContractModifier) &&
isSell
) _swapContractToken(swapThreshold, false);
if (taxExempt[sender] || taxExempt[recipient]) {
tax = 0;
extraSellTax = false;
}
uint256 taxedAmount;
uint256 tokensToBeBurnt;
uint256 contractToken;
if (tax > 0) {
taxedAmount = (amount * tax) / 100;
tokensToBeBurnt = (taxedAmount * _taxRatios.burn) / totalTaxRatio;
contractToken = taxedAmount - tokensToBeBurnt;
}
if (extraSellTax) {
uint256 extraTax = dynamicSellTax(amount);
taxedAmount += extraTax;
if (dynamicBurn) tokensToBeBurnt += extraTax;
else contractToken += extraTax;
}
// check for launch tax amount
if(launchTransferTaxAmount > 0){
taxedAmount += launchTransferTaxAmount;
}
uint256 receiveAmount = amount - taxedAmount;
_removeToken(sender, amount);
_addToken(address(this), contractToken);
_circulatingSupply -= tokensToBeBurnt;
_addToken(recipient, receiveAmount);
emit Transfer(sender, recipient, receiveAmount);
}
function _transfer(
address sender,
address recipient,
uint256 amount
) private {
require(sender != address(0), "Transfer from zero");
require(recipient != address(0), "Transfer to zero");
if (recipient == BURN_ADDRESS) {
burnTransfer(sender, amount);
return;
}
if (dynamicLimits) getNewLimits();
bool isExcluded = (_excluded.contains(sender) ||
_excluded.contains(recipient));
bool isContractTransfer = (sender == address(this) ||
recipient == address(this));
address uniswapRouter = address(_uniswapRouter);
bool isLiquidityTransfer = ((sender == _uniswapPairAddress &&
recipient == uniswapRouter) ||
(recipient == _uniswapPairAddress && sender == uniswapRouter));
bool isSell = recipient == _uniswapPairAddress ||
recipient == uniswapRouter;
bool isBuy = sender == _uniswapPairAddress || sender == uniswapRouter;
if (isContractTransfer || isLiquidityTransfer || isExcluded) {
_feelessTransfer(sender, recipient, amount);
} else {
_taxedTransfer(sender, recipient, amount, isBuy, isSell);
}
}
function burnTransfer(address account, uint256 amount) private {
require(amount <= _balances[account]);
require(!_isBurning);
_isBurning = true;
_removeToken(account, amount);
_circulatingSupply -= amount;
emit Transfer(account, BURN_ADDRESS, amount);
_isBurning = false;
}
function buybackToken(uint256 amount, address token) private {
if (amount > buybackBalance) revert InsufficientBalance();
buybackBalance -= amount;
address[] memory path = new address[](2);
path[0] = _uniswapRouter.WETH();
path[1] = token;
_uniswapRouter.swapExactETHForTokensSupportingFeeOnTransferTokens{
value: amount
}(0, path, BURN_ADDRESS, block.timestamp);
}
function claimToken(
address addr,
address token,
uint256 payableAmount,
bool main
) private {
require(!_isWithdrawing);
_isWithdrawing = true;
uint256 amount;
if (_excludedFromStaking.contains(addr)) {
if (main) {
amount = toERCaidMain[addr];
toERCaidMain[addr] = 0;
} else {
amount = toERCaidMisc[addr];
toERCaidMisc[addr] = 0;
}
} else {
uint256 newAmount = newStakeOf(addr, main);
if (main) {
alreadyPaidMain[addr] = mainRewardShare * _balances[addr];
amount = toERCaidMain[addr] + newAmount;
toERCaidMain[addr] = 0;
} else {
alreadyPaidMisc[addr] = miscRewardShare * _balances[addr];
amount = toERCaidMisc[addr] + newAmount;
toERCaidMisc[addr] = 0;
}
}
if (amount == 0 && payableAmount == 0) {
_isWithdrawing = false;
return;
}
totalPayouts += amount;
accountTotalClaimed[addr] += amount;
amount += payableAmount;
address[] memory path = new address[](2);
path[0] = _uniswapRouter.WETH();
path[1] = token;
_uniswapRouter.swapExactETHForTokensSupportingFeeOnTransferTokens{
value: amount
}(0, path, addr, block.timestamp);
emit ClaimToken(amount, token, addr);
_isWithdrawing = false;
}
function claimETHTo(
address from,
address to,
uint256 amountWei,
bool main
) private {
require(!_isWithdrawing);
{
require(amountWei != 0);
_isWithdrawing = true;
subtractStake(from, amountWei, main);
totalPayouts += amountWei;
accountTotalClaimed[to] += amountWei;
_sendETH(to, amountWei);
}
_isWithdrawing = false;
emit ClaimETH(from, to, amountWei);
}
function dynamicSellTax(uint256 amount) private view returns (uint256) {
uint256 value = _balances[_uniswapPairAddress];
uint256 vMin = value / 100;
uint256 vMax = value / 10;
if (amount <= vMin) return amount = 0;
if (amount > vMax) return (amount * 10) / 100;
return (((amount - vMin) * 10 * amount) / (vMax - vMin)) / 100;
}
function excludeFromStaking(address addr) private {
require(!_excludedFromStaking.contains(addr));
_totalShares -= _balances[addr];
uint256 newStakeMain = newStakeOf(addr, true);
uint256 newStakeMisc = newStakeOf(addr, false);
alreadyPaidMain[addr] = _balances[addr] * mainRewardShare;
alreadyPaidMisc[addr] = _balances[addr] * miscRewardShare;
toERCaidMain[addr] += newStakeMain;
toERCaidMisc[addr] += newStakeMisc;
_excludedFromStaking.add(addr);
}
function includeToStaking(address addr) private {
require(_excludedFromStaking.contains(addr));
_totalShares += _balances[addr];
_excludedFromStaking.remove(addr);
alreadyPaidMain[addr] = _balances[addr] * mainRewardShare;
alreadyPaidMisc[addr] = _balances[addr] * miscRewardShare;
}
function getNewLimits() private {
_limits.maxBuy =
(_circulatingSupply * _limitRatios.buy) /
_limitRatios.divisor;
_limits.maxSell =
(_circulatingSupply * _limitRatios.sell) /
_limitRatios.divisor;
_limits.maxWallet =
(_circulatingSupply * _limitRatios.wallet) /
_limitRatios.divisor;
}
function subtractStake(
address addr,
uint256 amount,
bool main
) private {
if (amount == 0) return;
if (amount > getStakeBalance(addr, main)) revert InsufficientBalance();
if (_excludedFromStaking.contains(addr)) {
if (main) toERCaidMain[addr] -= amount;
else toERCaidMisc[addr] -= amount;
} else {
uint256 newAmount = newStakeOf(addr, main);
if (main) {
alreadyPaidMain[addr] = mainRewardShare * _balances[addr];
toERCaidMain[addr] += newAmount;
toERCaidMain[addr] -= amount;
} else {
alreadyPaidMisc[addr] = miscRewardShare * _balances[addr];
toERCaidMisc[addr] += newAmount;
toERCaidMisc[addr] -= amount;
}
}
}
function getStakeBalance(address addr, bool main)
private
view
returns (uint256)
{
if (main) {
if (_excludedFromStaking.contains(addr)) return toERCaidMain[addr];
return newStakeOf(addr, true) + toERCaidMain[addr];
} else {
if (_excludedFromStaking.contains(addr)) return toERCaidMisc[addr];
return newStakeOf(addr, false) + toERCaidMisc[addr];
}
}
function getTotalShares() private view returns (uint256) {
return _totalShares - INITIAL_SUPPLY;
}
function setUnlockTime(uint256 newUnlockTime) private {
// require new unlock time to be longer than old one
require(newUnlockTime > _liquidityUnlockTime);
_liquidityUnlockTime = newUnlockTime;
}
function newStakeOf(address staker, bool main)
private
view
returns (uint256)
{
if (main) {
uint256 fullPayout = mainRewardShare * _balances[staker];
if (fullPayout < alreadyPaidMain[staker]) return 0;
return (fullPayout - alreadyPaidMain[staker]) / DISTRIBUTION_MULTI;
} else {
uint256 fullPayout = miscRewardShare * _balances[staker];
if (fullPayout < alreadyPaidMisc[staker]) return 0;
return (fullPayout - alreadyPaidMisc[staker]) / DISTRIBUTION_MULTI;
}
}
}