Address
0xec54d281380bdbf0c41f26b52d8bf6edd2de36eeCurrent Holdings
$0.00
TXs sent
not counted
First Active
2024-03-25
block 19,946,547
Last Active
906 days ago
block 19,946,547
Funded By
not identified
Net worth historyi
No net-worth snapshots recorded yet
exact matchBabyTokensolc 0.8.19+commit.7dd6d404runtime exact · creation exact
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
/**
* ____ _______ _______ _
* | _ \| ____\ \/ /_ _|__ ___ | |___
* | | | | _| \ / | |/ _ \ / _ \| / __|
* | |_| | |___ / \ | | (_) | (_) | \__ \
* |____/|_____/_/\_\ |_|\___/ \___/|_|___/
*
* This smart contract was created effortlessly using the DEXTools Token Creator.
*
* 🌐 Website: https://www.dextools.io/
* 🐦 Twitter: https://twitter.com/DEXToolsApp
* 💬 Telegram: https://t.me/DEXToolsCommunity
*
* 🚀 Unleash the power of decentralized finances and tokenization with DEXTools Token Creator. Customize your token seamlessly. Manage your created tokens conveniently from your user panel - start creating your dream token today!
*/
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { Clones } from "@openzeppelin/contracts/proxy/Clones.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { SafeERC20NoRevert, BabyTokenDividendTracker } from "./BabyTokenDividendTracker.sol";
import { IUniswapV2Factory } from "./interfaces/IUniswapV2Factory.sol";
import { IUniswapV2Router02 } from "./interfaces/IUniswapV2Router02.sol";
import { IAntiBot } from "./interfaces/IAntiBot.sol";
enum TokenType {
Standard,
Liquidity,
LiquidityFee,
LiquidityBuySellFee,
Burn,
Baby
}
contract BabyToken is ERC20Upgradeable, OwnableUpgradeable {
using Address for address;
using Address for address payable;
using SafeERC20 for IERC20;
uint256 public constant VERSION = 1;
IUniswapV2Router02 public uniswapV2Router;
address public uniswapV2Pair;
bool private swapping;
BabyTokenDividendTracker public dividendTracker;
address public rewardToken;
uint256 public swapTokensAtAmount;
uint256 public tokenRewardsFee;
uint256 public liquidityFee;
uint256 public marketingFee;
uint256 public totalFees;
address public _marketingWalletAddress;
uint256 public gasForProcessing;
// exlcude from fees and max transaction amount
mapping(address => bool) private _isExcludedFromFees;
// store addresses that a automatic market maker pairs. Any transfer *to* these addresses
// could be subject to a maximum transfer amount
mapping(address => bool) public automatedMarketMakerPairs;
event ExcludeFromFees(address indexed account);
event ExcludeMultipleAccountsFromFees(address[] accounts);
event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);
event GasForProcessingUpdated(
uint256 indexed newValue,
uint256 indexed oldValue
);
event SwapAndLiquify(
uint256 tokensSwapped,
uint256 ethReceived,
uint256 tokensIntoLiqudity
);
event SendDividends(uint256 tokensSwapped, uint256 amount);
event ProcessedDividendTracker(
uint256 iterations,
uint256 claims,
uint256 lastProcessedIndex,
bool indexed automatic,
uint256 gas,
address indexed processor
);
IAntiBot public antiBot;
bool public enableAntiBot;
//@custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
function initialize(
address owner_,
string memory name_,
string memory symbol_,
uint256 totalSupply_,
address[5] memory addrs, // reward, router, marketing wallet, dividendTracker, antibot
uint256[3] memory feeSettings, // rewards, liquidity, marketing
uint256 minimumTokenBalanceForDividends_,
bool enableAntiBot_
) external initializer {
__ERC20_init(name_, symbol_);
__Ownable_init();
transferOwnership(owner_);
rewardToken = addrs[0];
_marketingWalletAddress = addrs[2];
require(
owner_ != _marketingWalletAddress,
"Owner and marketing wallet cannot be the same"
);
require(
!_marketingWalletAddress.isContract(),
"Marketing wallet cannot be a contract"
);
if (enableAntiBot_) {
antiBot = IAntiBot(addrs[4]);
antiBot.setTokenOwner(owner());
enableAntiBot = true;
}
tokenRewardsFee = feeSettings[0];
liquidityFee = feeSettings[1];
marketingFee = feeSettings[2];
totalFees = tokenRewardsFee + liquidityFee + marketingFee;
require(totalFees <= 20, "Total fee is over 20%");
swapTokensAtAmount = totalSupply_ / 1000; // 0.1%
// use by default 300,000 gas to process auto-claiming dividends
gasForProcessing = 300000;
dividendTracker = BabyTokenDividendTracker(
payable(Clones.clone(addrs[3]))
);
dividendTracker.initialize(
rewardToken,
minimumTokenBalanceForDividends_
);
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(addrs[1]);
// Create a uniswap pair for this new token
address _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
.createPair(address(this), _uniswapV2Router.WETH());
uniswapV2Router = _uniswapV2Router;
uniswapV2Pair = _uniswapV2Pair;
_setAutomatedMarketMakerPair(_uniswapV2Pair, true);
// exclude from receiving dividends
dividendTracker.excludeFromDividends(address(dividendTracker));
dividendTracker.excludeFromDividends(address(this));
dividendTracker.excludeFromDividends(owner());
dividendTracker.excludeFromDividends(address(0xdead));
dividendTracker.excludeFromDividends(address(_uniswapV2Router));
// exclude from paying fees or having max transaction amount
_isExcludedFromFees[owner()] = true;
_isExcludedFromFees[_marketingWalletAddress] = true;
_isExcludedFromFees[address(this)] = true;
/*
_mint is an internal function in ERC20.sol that is only called here,
and CANNOT be called ever again
*/
_mint(owner(), totalSupply_);
}
receive() external payable {}
function setSwapTokensAtAmount(uint256 amount) external onlyOwner {
require(
amount > totalSupply() / 10 ** 5,
"BabyToken: Amount must be greater than 0.001% of total supply"
);
swapTokensAtAmount = amount;
}
function excludeFromFees(address account) external onlyOwner {
require(
!_isExcludedFromFees[account],
"BabyToken: Account is already excluded"
);
_isExcludedFromFees[account] = true;
emit ExcludeFromFees(account);
}
function excludeMultipleAccountsFromFees(
address[] calldata accounts
) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
_isExcludedFromFees[accounts[i]] = true;
}
emit ExcludeMultipleAccountsFromFees(accounts);
}
function setMarketingWallet(address payable wallet) external onlyOwner {
require(
wallet != address(0),
"BabyToken: The marketing wallet cannot be the value of zero"
);
require(!wallet.isContract(), "Marketing wallet cannot be a contract");
_marketingWalletAddress = wallet;
}
function setTokenRewardsFee(uint256 value) external onlyOwner {
tokenRewardsFee = value;
totalFees = tokenRewardsFee + liquidityFee + marketingFee;
require(totalFees <= 20, "Total fee is over 20%");
}
function setLiquidityFee(uint256 value) external onlyOwner {
liquidityFee = value;
totalFees = tokenRewardsFee + liquidityFee + marketingFee;
require(totalFees <= 20, "Total fee is over 20%");
}
function setMarketingFee(uint256 value) external onlyOwner {
marketingFee = value;
totalFees = tokenRewardsFee + liquidityFee + marketingFee;
require(totalFees <= 20, "Total fee is over 20%");
}
function addToBlacklist(address[] calldata addresses) external onlyOwner {
require(enableAntiBot, "antibot not enabled");
antiBot.addToBlacklist(_msgSender(), addresses);
}
function removeFromBlacklist(address addr) external onlyOwner {
require(enableAntiBot, "antibot not enabled");
antiBot.removeFromBlacklist(_msgSender(), addr);
}
function getBlacklistStatus()
external
view
returns (bool, uint256, uint256, uint256, uint256)
{
if (enableAntiBot == false) return (false, 0, 0, 0, 0);
(
uint256 creationTime,
uint256 blacklistTime,
uint256 blacklistLimit,
uint256 blacklistSize
) = antiBot.getBlacklistStatus(address(this));
return (
enableAntiBot,
creationTime,
blacklistTime,
blacklistLimit,
blacklistSize
);
}
function getBlacklist() external view returns (address[] memory) {
require(enableAntiBot, "antibot not enabled");
return antiBot.getBlacklist(address(this));
}
function isBlacklisted(address account) external view returns (bool) {
require(enableAntiBot, "antibot not enabled");
return antiBot.isBlacklisted(address(this), account);
}
function _setAutomatedMarketMakerPair(address pair, bool value) private {
require(
automatedMarketMakerPairs[pair] != value,
"BabyToken: Automated market maker pair is already set to that value"
);
automatedMarketMakerPairs[pair] = value;
if (value) {
dividendTracker.excludeFromDividends(pair);
}
emit SetAutomatedMarketMakerPair(pair, value);
}
function updateGasForProcessing(uint256 newValue) public onlyOwner {
require(
newValue >= 200000 && newValue <= 500000,
"BabyToken: gasForProcessing must be between 200,000 and 500,000"
);
require(
newValue != gasForProcessing,
"BabyToken: Cannot update gasForProcessing to same value"
);
emit GasForProcessingUpdated(newValue, gasForProcessing);
gasForProcessing = newValue;
}
function updateClaimWait(uint256 claimWait) external onlyOwner {
dividendTracker.updateClaimWait(claimWait);
}
function getClaimWait() external view returns (uint256) {
return dividendTracker.claimWait();
}
function updateMinimumTokenBalanceForDividends(
uint256 amount
) external onlyOwner {
dividendTracker.updateMinimumTokenBalanceForDividends(amount);
}
function getMinimumTokenBalanceForDividends()
external
view
returns (uint256)
{
return dividendTracker.minimumTokenBalanceForDividends();
}
function getTotalDividendsDistributed() external view returns (uint256) {
return dividendTracker.totalDividendsDistributed();
}
function isExcludedFromFees(address account) public view returns (bool) {
return _isExcludedFromFees[account];
}
function withdrawableDividendOf(
address account
) public view returns (uint256) {
return dividendTracker.withdrawableDividendOf(account);
}
function dividendTokenBalanceOf(
address account
) public view returns (uint256) {
return dividendTracker.balanceOf(account);
}
function excludeFromDividends(address account) external onlyOwner {
dividendTracker.excludeFromDividends(account);
}
function isExcludedFromDividends(
address account
) public view returns (bool) {
return dividendTracker.isExcludedFromDividends(account);
}
function getAccountDividendsInfo(
address account
)
external
view
returns (
address,
int256,
int256,
uint256,
uint256,
uint256,
uint256,
uint256
)
{
return dividendTracker.getAccount(account);
}
function getAccountDividendsInfoAtIndex(
uint256 index
)
external
view
returns (
address,
int256,
int256,
uint256,
uint256,
uint256,
uint256,
uint256
)
{
return dividendTracker.getAccountAtIndex(index);
}
function processDividendTracker(uint256 gas) external {
(
uint256 iterations,
uint256 claims,
uint256 lastProcessedIndex
) = dividendTracker.process(gas);
emit ProcessedDividendTracker(
iterations,
claims,
lastProcessedIndex,
false,
gas,
tx.origin // solhint-disable-line avoid-tx-origin
);
}
function claim() external {
dividendTracker.processAccount(payable(msg.sender), false);
}
function getLastProcessedIndex() external view returns (uint256) {
return dividendTracker.getLastProcessedIndex();
}
function getNumberOfDividendTokenHolders() external view returns (uint256) {
return dividendTracker.getNumberOfTokenHolders();
}
function _transfer(
address from,
address to,
uint256 amount
) internal override {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
if (amount == 0) {
super._transfer(from, to, 0);
return;
}
if (enableAntiBot) {
antiBot.onPreTransferCheck(from, to);
}
uint256 contractTokenBalance = balanceOf(address(this));
bool canSwap = contractTokenBalance >= swapTokensAtAmount;
if (
canSwap &&
!swapping &&
!automatedMarketMakerPairs[from] &&
from != owner() &&
to != owner() &&
totalFees > 0
) {
swapping = true;
if (marketingFee > 0) {
uint256 marketingTokens = (contractTokenBalance *
marketingFee) / totalFees;
swapAndSendToFee(marketingTokens);
}
if (liquidityFee > 0) {
uint256 swapTokens = (contractTokenBalance * liquidityFee) /
totalFees;
swapAndLiquify(swapTokens);
}
uint256 sellTokens = balanceOf(address(this));
if (sellTokens > 0) {
swapAndSendDividends(sellTokens);
}
swapping = false;
}
bool takeFee = !swapping;
// if any account belongs to _isExcludedFromFee account then remove the fee
if (_isExcludedFromFees[from] || _isExcludedFromFees[to]) {
takeFee = false;
}
if (takeFee && totalFees > 0) {
uint256 fees = (amount * totalFees) / 100;
amount = amount - fees;
super._transfer(from, address(this), fees);
}
super._transfer(from, to, amount);
try
dividendTracker.setBalance(payable(from), balanceOf(from))
{} catch {}
try dividendTracker.setBalance(payable(to), balanceOf(to)) {} catch {}
if (!swapping) {
uint256 gas = gasForProcessing;
try dividendTracker.process(gas) returns (
uint256 iterations,
uint256 claims,
uint256 lastProcessedIndex
) {
emit ProcessedDividendTracker(
iterations,
claims,
lastProcessedIndex,
true,
gas,
tx.origin // solhint-disable-line avoid-tx-origin
);
} catch {}
}
}
function swapAndSendToFee(uint256 tokens) private {
uint256 initialCAKEBalance = IERC20(rewardToken).balanceOf(
address(this)
);
swapTokensForCake(tokens);
uint256 newBalance = IERC20(rewardToken).balanceOf(address(this)) -
initialCAKEBalance;
IERC20(rewardToken).safeTransfer(_marketingWalletAddress, newBalance);
}
function swapAndLiquify(uint256 tokens) private {
// split the contract balance into halves
uint256 half = tokens / 2;
uint256 otherHalf = tokens - half;
// capture the contract's current ETH balance.
// this is so that we can capture exactly the amount of ETH that the
// swap creates, and not make the liquidity event include any ETH that
// has been manually sent to the contract
uint256 initialBalance = address(this).balance;
// swap tokens for ETH
swapTokensForEth(half); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered
// how much ETH did we just swap into?
uint256 newBalance = address(this).balance - initialBalance;
// add liquidity to uniswap
addLiquidity(otherHalf, newBalance);
emit SwapAndLiquify(half, newBalance, otherHalf);
}
function swapTokensForEth(uint256 tokenAmount) private {
// generate the uniswap pair path of token -> weth
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
_approve(address(this), address(uniswapV2Router), tokenAmount);
// make the swap
uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
0, // accept any amount of ETH
path,
address(this),
block.timestamp
);
}
function swapTokensForCake(uint256 tokenAmount) private {
address[] memory path = new address[](3);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
path[2] = rewardToken;
_approve(address(this), address(uniswapV2Router), tokenAmount);
// make the swap
uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
address(this),
block.timestamp
);
}
function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
// approve token transfer to cover all possible scenarios
_approve(address(this), address(uniswapV2Router), tokenAmount);
// add the liquidity
uniswapV2Router.addLiquidityETH{ value: ethAmount }(
address(this),
tokenAmount,
0, // slippage is unavoidable
0, // slippage is unavoidable
address(0xdead),
block.timestamp
);
}
function swapAndSendDividends(uint256 tokens) private {
swapTokensForCake(tokens);
uint256 dividends = IERC20(rewardToken).balanceOf(address(this));
bool success = SafeERC20NoRevert.safeTransfer(
IERC20(rewardToken),
address(dividendTracker),
dividends
);
if (success) {
dividendTracker.distributeCAKEDividends(dividends);
emit SendDividends(tokens, dividends);
}
}
}