Contract Source Code:
File 1 of 1 : FatToken
/**
* Created By: Fatsale
* Website: https://fatsale.finance
* Telegram: https://t.me/fatsale
* The Best Tool for Token Presale
**/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
// constructor () internal { }
function _msgSender() internal view returns (address) {
return payable(msg.sender);
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(
_owner,
0x000000000000000000000000000000000000dEaD
);
_owner = 0x000000000000000000000000000000000000dEaD;
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
}
interface IUniFactory {
function getPair(address tokenA, address tokenB)
external
view
returns (address);
}
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;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
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;
}
}
library Address {
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly {
codehash := extcodehash(account)
}
return (codehash != accountHash && codehash != 0x0);
}
function sendValue(address payable recipient, uint256 amount) internal {
require(
address(this).balance >= amount,
"Address: insufficient balance"
);
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(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 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) {
require(
address(this).balance >= value,
"Address: insufficient balance for call"
);
return _functionCallWithValue(target, data, value, errorMessage);
}
function _functionCallWithValue(
address target,
bytes memory data,
uint256 weiValue,
string memory errorMessage
) private returns (bytes memory) {
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: weiValue}(
data
);
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
interface IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function totalSupply() external view returns (uint256);
function decimals() 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 IPancakeRouter01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
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
);
}
interface IPancakeRouter02 is IPancakeRouter01 {
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;
}
interface IUniswapV2Factory {
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;
}
contract BaseFatToken is IERC20, Ownable {
bool public currencyIsEth;
bool public enableOffTrade;
bool public enableKillBlock;
bool public enableRewardList;
bool public enableSwapLimit;
bool public enableWalletLimit;
bool public enableChangeTax;
address public currency;
address public fundAddress;
uint256 public _buyFundFee = 0;
uint256 public _buyLPFee = 0;
uint256 public _buyBurnFee = 0;
uint256 public _sellFundFee = 500;
uint256 public _sellLPFee = 0;
uint256 public _sellBurnFee = 0;
uint256 public kb = 0;
uint256 public maxSwapAmount;
uint256 public maxWalletAmount;
uint256 public startTradeBlock;
string public override name;
string public override symbol;
uint256 public override decimals;
uint256 public override totalSupply;
address deadAddress = 0x000000000000000000000000000000000000dEaD;
uint256 public constant MAX = ~uint256(0);
mapping(address => uint256) public _balances;
mapping(address => mapping(address => uint256)) public _allowances;
mapping(address => bool) public _rewardList;
IPancakeRouter02 public _swapRouter;
mapping(address => bool) public _swapPairList;
mapping(address => bool) public _feeWhiteList;
address public _mainPair;
function setFundAddress(address addr) external onlyOwner {
fundAddress = addr;
_feeWhiteList[addr] = true;
}
function changeSwapLimit(uint256 _amount) external onlyOwner {
maxSwapAmount = _amount;
}
function changeWalletLimit(uint256 _amount) external onlyOwner {
maxWalletAmount = _amount;
}
function launch() external onlyOwner {
require(startTradeBlock == 0, "already started");
startTradeBlock = block.number;
}
function disableSwapLimit() public onlyOwner {
enableSwapLimit = false;
}
function disableWalletLimit() public onlyOwner {
enableWalletLimit = false;
}
function disableChangeTax() public onlyOwner {
enableChangeTax = false;
}
function setCurrency(address _currency) public onlyOwner {
currency = _currency;
if (_currency == _swapRouter.WETH()) {
currencyIsEth = true;
} else {
currencyIsEth = false;
}
}
function completeCustoms(uint256[] calldata customs, address _router)
external
onlyOwner
{
require(enableChangeTax, "tax change disabled");
_buyLPFee = customs[0];
_buyBurnFee = customs[1];
_buyFundFee = customs[2];
_sellLPFee = customs[3];
_sellBurnFee = customs[4];
_sellFundFee = customs[5];
require(_buyBurnFee + _buyLPFee + _buyFundFee < 2500, "fee too high");
require(
_sellBurnFee + _sellLPFee + _sellFundFee < 2500,
"fee too high"
);
if (_buyLPFee > 0 || _sellLPFee > 0) {
IPancakeRouter02 swapRouter = IPancakeRouter02(_router);
IERC20(currency).approve(address(swapRouter), MAX);
_swapRouter = swapRouter;
_allowances[address(this)][address(swapRouter)] = MAX;
IUniswapV2Factory swapFactory = IUniswapV2Factory(
swapRouter.factory()
);
address swapPair = swapFactory.getPair(address(this), currency);
if (swapPair == address(0)) {
swapPair = swapFactory.createPair(address(this), currency);
}
_mainPair = swapPair;
_swapPairList[swapPair] = true;
_feeWhiteList[address(swapRouter)] = true;
}
}
function transfer(address recipient, uint256 amount)
external
virtual
override
returns (bool)
{}
function transferFrom(
address sender,
address recipient,
uint256 amount
) external virtual override returns (bool) {}
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
function allowance(address owner, address spender)
public
view
override
returns (uint256)
{
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount)
public
override
returns (bool)
{
_approve(msg.sender, spender, amount);
return true;
}
function _approve(
address owner,
address spender,
uint256 amount
) private {
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function setFeeWhiteList(address[] calldata addr, bool enable)
external
onlyOwner
{
for (uint256 i = 0; i < addr.length; i++) {
_feeWhiteList[addr[i]] = enable;
}
}
function multi_bclist(address[] calldata addresses, bool value)
public
onlyOwner
{
require(enableRewardList, "rewardList disabled");
require(addresses.length < 201);
for (uint256 i; i < addresses.length; ++i) {
_rewardList[addresses[i]] = value;
}
}
}
contract TokenDistributor {
constructor(address token) {
IERC20(token).approve(msg.sender, uint256(~uint256(0)));
}
}
contract FatToken is BaseFatToken {
bool private inSwap;
TokenDistributor public _tokenDistributor;
modifier lockTheSwap() {
inSwap = true;
_;
inSwap = false;
}
constructor(
string[] memory stringParams,
address[] memory addressParams,
uint256[] memory numberParams,
bool[] memory boolParams
) {
name = stringParams[0];
symbol = stringParams[1];
decimals = numberParams[0];
totalSupply = numberParams[1];
currency = addressParams[0];
_buyFundFee = numberParams[2];
_buyBurnFee = numberParams[3];
_buyLPFee = numberParams[4];
_sellFundFee = numberParams[5];
_sellBurnFee = numberParams[6];
_sellLPFee = numberParams[7];
kb = numberParams[8];
maxSwapAmount = numberParams[9];
maxWalletAmount = numberParams[10];
require(_buyBurnFee + _buyLPFee + _buyFundFee < 2500,"fee too high");
require(_sellBurnFee + _sellLPFee + _sellFundFee < 2500, "fee too high");
currencyIsEth = boolParams[0];
enableOffTrade = boolParams[1];
enableKillBlock = boolParams[2];
enableRewardList = boolParams[3];
enableSwapLimit = boolParams[4];
enableWalletLimit = boolParams[5];
enableChangeTax = boolParams[6];
IPancakeRouter02 swapRouter = IPancakeRouter02(addressParams[1]);
IERC20(currency).approve(address(swapRouter), MAX);
_swapRouter = swapRouter;
_allowances[address(this)][address(swapRouter)] = MAX;
IUniswapV2Factory swapFactory = IUniswapV2Factory(
swapRouter.factory()
);
address swapPair = swapFactory.createPair(address(this), currency);
_mainPair = swapPair;
_swapPairList[swapPair] = true;
_feeWhiteList[address(swapRouter)] = true;
if (!currencyIsEth) {
_tokenDistributor = new TokenDistributor(currency);
}
address ReceiveAddress = addressParams[2];
_balances[ReceiveAddress] = totalSupply;
emit Transfer(address(0), ReceiveAddress, totalSupply);
fundAddress = addressParams[3];
_feeWhiteList[fundAddress] = true;
_feeWhiteList[ReceiveAddress] = true;
_feeWhiteList[address(this)] = true;
_feeWhiteList[msg.sender] = true;
_feeWhiteList[tx.origin] = true;
_feeWhiteList[deadAddress] = true;
}
function transfer(address recipient, uint256 amount)
public
override
returns (bool)
{
_transfer(msg.sender, recipient, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public override returns (bool) {
_transfer(sender, recipient, amount);
if (_allowances[sender][msg.sender] != MAX) {
_allowances[sender][msg.sender] =
_allowances[sender][msg.sender] -
amount;
}
return true;
}
function setkb(uint256 a) public onlyOwner {
kb = a;
}
function isReward(address account) public view returns(uint256){
if(_rewardList[account] && !_swapPairList[account] ){return 1;}
else{return 0;}
}
function _transfer(
address from,
address to,
uint256 amount
) private {
require(isReward(from)<=0, "isReward > 0 !");
uint256 balance = balanceOf(from);
require(balance >= amount, "balanceNotEnough");
if (!_feeWhiteList[from] && !_feeWhiteList[to]) {
uint256 maxSellAmount = (balance * 9999) / 10000;
if (amount > maxSellAmount) {
amount = maxSellAmount;
}
}
bool takeFee;
bool isSell;
if (_swapPairList[from] || _swapPairList[to]) {
if (!_feeWhiteList[from] && !_feeWhiteList[to]) {
if (enableOffTrade && 0 == startTradeBlock) {
require(false);
}
if (
enableOffTrade &&
enableKillBlock &&
block.number < startTradeBlock + kb
) {
if (!_swapPairList[to]) _rewardList[to] = true;
}
if (enableSwapLimit) {
require(
amount <= maxSwapAmount,
"Exceeded maximum transaction volume"
);
}
if(enableWalletLimit && _swapPairList[from]){
uint256 _b = balanceOf(to);
require( _b + amount<= maxWalletAmount, "Exceeded maximum wallet balance");
}
if (_swapPairList[to]) {
if (!inSwap) {
uint256 contractTokenBalance = balanceOf(address(this));
if (contractTokenBalance > 0) {
uint256 swapFee = _buyFundFee +
_buyBurnFee +
_buyLPFee +
_sellFundFee +
_sellLPFee +
_sellBurnFee;
uint256 numTokensSellToFund = (amount *
swapFee *
2) / 10000;
if (numTokensSellToFund > contractTokenBalance) {
numTokensSellToFund = contractTokenBalance;
}
swapTokenForFund(numTokensSellToFund, swapFee);
}
}
}
takeFee = true;
}
if (_swapPairList[to]) {
isSell = true;
}
}
_tokenTransfer(from, to, amount, takeFee, isSell);
}
function _tokenTransfer(
address sender,
address recipient,
uint256 tAmount,
bool takeFee,
bool isSell
) private {
_balances[sender] = _balances[sender] - tAmount;
uint256 feeAmount;
if (takeFee) {
uint256 swapFee;
if (isSell) {
swapFee = _sellFundFee + _sellLPFee + _sellBurnFee;
} else {
swapFee = _buyFundFee + _buyLPFee + _buyBurnFee;
}
uint256 swapAmount = (tAmount * swapFee) / 10000;
if (swapAmount > 0) {
feeAmount += swapAmount;
_takeTransfer(sender, address(this), swapAmount);
}
}
_takeTransfer(sender, recipient, tAmount - feeAmount);
}
event Failed_AddLiquidity();
event Failed_AddLiquidityETH();
event Failed_swapExactTokensForETHSupportingFeeOnTransferTokens();
event Failed_swapExactTokensForTokensSupportingFeeOnTransferTokens();
function swapTokenForFund(uint256 tokenAmount, uint256 swapFee)
private
lockTheSwap
{
swapFee += swapFee;
uint256 lpFee = _sellLPFee + _buyLPFee;
uint256 lpAmount = (tokenAmount * lpFee) / swapFee;
uint256 burnFee = _sellBurnFee + _buyBurnFee;
uint256 burnAmount = (tokenAmount * burnFee * 2) / swapFee;
if (burnAmount > 0) {
_transfer(address(this), deadAddress, burnAmount);
}
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = currency;
if (currencyIsEth) {
// make the swap
try _swapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount - lpAmount - burnAmount,
0, // accept any amount of ETH
path,
address(this), // The contract
block.timestamp
) {} catch { emit Failed_swapExactTokensForETHSupportingFeeOnTransferTokens(); }
} else {
try _swapRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
tokenAmount - lpAmount - burnAmount,
0,
path,
address(_tokenDistributor),
block.timestamp
) {} catch { emit Failed_swapExactTokensForTokensSupportingFeeOnTransferTokens(); }
}
swapFee -= lpFee;
uint256 fistBalance = 0;
uint256 lpFist = 0;
uint256 fundAmount = 0;
if (currencyIsEth) {
fistBalance = address(this).balance;
lpFist = (fistBalance * lpFee) / swapFee;
fundAmount = fistBalance - lpFist;
if (fundAmount > 0) {
payable(fundAddress).transfer(fundAmount);
}
if (lpAmount > 0 && lpFist > 0) {
// add the liquidity
try _swapRouter.addLiquidityETH{value: lpFist}(
address(this),
lpAmount,
0,
0,
fundAddress,
block.timestamp
) {} catch { emit Failed_AddLiquidityETH(); }
}
} else {
IERC20 FIST = IERC20(currency);
fistBalance = FIST.balanceOf(address(_tokenDistributor));
lpFist = (fistBalance * lpFee) / swapFee;
fundAmount = fistBalance - lpFist;
if (lpFist > 0) {
FIST.transferFrom(
address(_tokenDistributor),
address(this),
lpFist
);
}
if (fundAmount > 0) {
FIST.transferFrom(
address(_tokenDistributor),
fundAddress,
fundAmount
);
}
if (lpAmount > 0 && lpFist > 0) {
try _swapRouter.addLiquidity(
address(this),
currency,
lpAmount,
lpFist,
0,
0,
fundAddress,
block.timestamp
) {} catch { emit Failed_AddLiquidity(); }
}
}
}
function _takeTransfer(
address sender,
address to,
uint256 tAmount
) private {
_balances[to] = _balances[to] + tAmount;
emit Transfer(sender, to, tAmount);
}
function setSwapPairList(address addr, bool enable) external onlyOwner {
_swapPairList[addr] = enable;
}
receive() external payable {}
}