文件 1 的 1:CoinTensorAI.sol
pragma solidity 0.8.19;
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;
}
}
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 IUniswapV2Factory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
interface IUniswapV2Router02 {
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
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 swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
}
contract Ownable is Context {
address private _owner;
mapping (address => bool) internal authorizations;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
authorizations[_owner] = true;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
modifier authorized() {
require(isAuthorized(msg.sender), "Ownable: caller is not authorized"); _;
}
function isAuthorized(address account) public view returns (bool) {
return authorizations[account];
}
function authorize(address account) public onlyOwner {
authorizations[account] = true;
}
function unauthorize(address account) public onlyOwner {
authorizations[account] = false;
}
function transferOwnership(address payable _account) public onlyOwner {
emit OwnershipTransferred(_owner, _account);
_owner = _account;
authorizations[_account] = true;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
}
interface IDividendDistributor {
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external;
function setShare(address shareholder, uint256 amount) external;
function deposit() external payable;
function process(uint256 gas) external;
}
contract DividendDistributor is IDividendDistributor {
using SafeMath for uint256;
address _token;
struct Share {
uint256 amount;
uint256 totalExcluded;
uint256 totalRealised;
}
IERC20 wethAddress = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
IUniswapV2Router02 uniswapV2Router;
address uniswapV2Pair;
address[] shareholders;
mapping (address => uint256) shareholderIndexes;
mapping (address => uint256) shareholderClaims;
mapping (address => Share) public shares;
uint256 public totalShares;
uint256 public totalDividends;
uint256 public totalDistributed;
uint256 public dividendsPerShare;
uint256 public dividendsPerShareAccuracyFactor = 10 ** 36;
uint256 public minPeriod = 30 * 60;
uint256 public minDistribution = 1 * (10 ** 12);
uint256 currentIndex;
bool initialized;
modifier initialization() {
require(!initialized);
_;
initialized = true;
}
modifier onlyToken() {
require(msg.sender == _token); _;
}
constructor (address _router) {
uniswapV2Router = _router != address(0)
? IUniswapV2Router02(_router)
: IUniswapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E);
_token = msg.sender;
}
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external override onlyToken {
minPeriod = _minPeriod;
minDistribution = _minDistribution;
}
function setShare(address shareholder, uint256 amount) external override onlyToken {
if(shares[shareholder].amount > 0){
distributeDividend(shareholder);
}
if(amount > 0 && shares[shareholder].amount == 0){
addShareholder(shareholder);
}else if(amount == 0 && shares[shareholder].amount > 0){
removeShareholder(shareholder);
}
totalShares = totalShares.sub(shares[shareholder].amount).add(amount);
shares[shareholder].amount = amount;
shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
}
function deposit() external payable override onlyToken {
uint256 balanceBefore = wethAddress.balanceOf(address(this));
address[] memory path = new address[](2);
path[0] = address(wethAddress);
uniswapV2Router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(
0,
path,
address(this),
block.timestamp
);
uint256 amount = wethAddress.balanceOf(address(this)).sub(balanceBefore);
totalDividends = totalDividends.add(amount);
dividendsPerShare = dividendsPerShare.add(dividendsPerShareAccuracyFactor.mul(amount).div(totalShares));
}
function process(uint256 gas) external override onlyToken {
uint256 shareholderCount = shareholders.length;
if(shareholderCount == 0) { return; }
uint256 gasUsed = 0;
uint256 gasLeft = gasleft();
uint256 iterations = 0;
while(gasUsed < gas && iterations < shareholderCount) {
if(currentIndex >= shareholderCount){
currentIndex = 0;
}
if(shouldDistribute(shareholders[currentIndex])){
distributeDividend(shareholders[currentIndex]);
}
gasUsed = gasUsed.add(gasLeft.sub(gasleft()));
gasLeft = gasleft();
currentIndex++;
iterations++;
}
}
function shouldDistribute(address shareholder) internal view returns (bool) {
return shareholderClaims[shareholder] + minPeriod < block.timestamp
&& getUnpaidEarnings(shareholder) > minDistribution;
}
function distributeDividend(address shareholder) internal {
if(shares[shareholder].amount == 0){ return; }
uint256 amount = getUnpaidEarnings(shareholder);
if(amount > 0){
totalDistributed = totalDistributed.add(amount);
wethAddress.transfer(shareholder, amount);
shareholderClaims[shareholder] = block.timestamp;
shares[shareholder].totalRealised = shares[shareholder].totalRealised.add(amount);
shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
}
}
function claimDividend(address shareholder) external onlyToken{
distributeDividend(shareholder);
}
function getUnpaidEarnings(address shareholder) public view returns (uint256) {
if(shares[shareholder].amount == 0){ return 0; }
uint256 shareholderTotalDividends = getCumulativeDividends(shares[shareholder].amount);
uint256 shareholderTotalExcluded = shares[shareholder].totalExcluded;
if(shareholderTotalDividends <= shareholderTotalExcluded){ return 0; }
return shareholderTotalDividends.sub(shareholderTotalExcluded);
}
function getCumulativeDividends(uint256 share) internal view returns (uint256) {
return share.mul(dividendsPerShare).div(dividendsPerShareAccuracyFactor);
}
function addShareholder(address shareholder) internal {
shareholderIndexes[shareholder] = shareholders.length;
shareholders.push(shareholder);
}
function removeShareholder(address shareholder) internal {
shareholders[shareholderIndexes[shareholder]] = shareholders[shareholders.length-1];
shareholderIndexes[shareholders[shareholders.length-1]] = shareholderIndexes[shareholder];
shareholders.pop();
}
}
contract CoinTensorAI is Context, IERC20, Ownable {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
mapping (address => bool) private _isExcludedFromFee;
mapping (address => bool) isDividendExempt;
mapping (address => bool) public isBlacklisted;
mapping(address => uint256) private _holderLastTransferTimestamp;
address payable private _taxWallet;
address payable private _mktWallet;
address private constant deadAddress = address(0xdead);
address private constant zeroAddress = address(0x0000);
address private constant wethAddress = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address public autoLiquidityReceiver;
address public marketingTaxReceiver;
uint256 private liquidityTax;
uint256 private reflectionTax;
uint256 private tax;
uint256 private totalTax;
uint256 private feeDenominator = 100;
uint256 targetLiquidity = 20;
uint256 targetLiquidityDenominator = 100;
DividendDistributor distributor;
uint256 distributorGas = 500000;
string private constant _name = unicode"CoinTensor AI";
string private constant _symbol = unicode"TENSOR";
uint8 private constant _decimals = 9;
uint256 private constant _tTotal = 30000000 * 10**_decimals;
uint256 public liquidityTaxBuy = 0;
uint256 public reflectionTaxBuy = 0;
uint256 public taxBuy = 25;
uint256 public totalTaxBuy = 25;
uint256 public liquidityTaxSell = 0;
uint256 public reflectionTaxSell = 0;
uint256 public taxSell = 25;
uint256 public totalTaxSell = 25;
bool public transferDelayEnabled = true;
uint256 private constant _preventSwapBefore=150;
uint256 private _buyCount=0;
uint256 public _taxSwapThreshold = 15000;
uint256 public _maxTxAmount = 300000 * 10**_decimals;
uint256 public _maxWalletSize = 300000 * 10**_decimals;
uint256 public _maxTaxSwap = 300000 * 10**_decimals;
IUniswapV2Router02 private uniswapV2Router;
address private uniswapV2Pair;
bool private tradingOpen;
bool private inSwap = false;
bool private swapEnabled = false;
event AutoLiquify(uint256 amountETH, uint256 amountEOG);
event LimitRemoved();
event TaxUpdated(uint256 buyTax, uint256 sellTax);
event TradingOpened();
modifier lockTheSwap {
inSwap = true;
_;
inSwap = false;
}
constructor (address taxWallet, address mktWallet) {
_taxWallet = payable(taxWallet);
_mktWallet = payable(mktWallet);
_balances[_msgSender()] = _tTotal;
distributor = new DividendDistributor(address(uniswapV2Router));
isDividendExempt[uniswapV2Pair] = true;
isDividendExempt[address(this)] = true;
isDividendExempt[deadAddress] = true;
isDividendExempt[zeroAddress] = true;
autoLiquidityReceiver = owner();
marketingTaxReceiver = owner();
excludeFromFee(owner(), true);
excludeFromFee(address(this), true);
excludeFromFee(deadAddress, true);
excludeFromFee(zeroAddress, true);
excludeFromFee(_taxWallet, true);
excludeFromFee(_mktWallet, true);
emit Transfer(address(0), _msgSender(), _tTotal);
}
function name() public pure returns (string memory) {
return _name;
}
function symbol() public pure returns (string memory) {
return _symbol;
}
function decimals() public pure returns (uint8) {
return _decimals;
}
function totalSupply() public pure override returns (uint256) {
return _tTotal;
}
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
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(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
function _approve(address owner, address spender, uint256 amount) private {
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 _transfer(address from, address to, uint256 amount) private {
require(!isBlacklisted[to] && !isBlacklisted[from], "_transfer: address is blacklisted");
require(from != address(0) && to != address(0), "_transfer: transfer the zero address");
require(amount > 0, "_transfer: Transfer amount must be greater than zero");
if (from != owner() && to != owner()) {
if (transferDelayEnabled) {
if (to != address(uniswapV2Router) && to != address(uniswapV2Pair)) {
require(
_holderLastTransferTimestamp[tx.origin] <
block.number,
"_transfer:: Transfer Delay enabled. Only one purchase per block allowed."
);
_holderLastTransferTimestamp[tx.origin] = block.number;
}
}
if (from == uniswapV2Pair && to != address(uniswapV2Router) && !_isExcludedFromFee[to]) {
require(amount <= _maxTxAmount, "_transfer: Exceeds the _maxTxAmount.");
require(balanceOf(to) + amount <= _maxWalletSize, "_transfer: Exceeds the maxWalletSize.");
_buyCount++;
}
if ( to == uniswapV2Pair && from != address(this)){
liquidityTax = liquidityTaxSell;
reflectionTax = reflectionTaxSell;
tax = taxSell;
totalTax = totalTaxSell;
} else if (from == uniswapV2Pair && to != address(this)){
liquidityTax = liquidityTaxBuy;
reflectionTax = reflectionTaxBuy;
tax = taxBuy;
totalTax = totalTaxBuy;
}
uint256 contractTokenBalance = balanceOf(address(this));
if (!inSwap && msg.sender != uniswapV2Pair && swapEnabled &&
contractTokenBalance > _taxSwapThreshold &&
_buyCount > _preventSwapBefore
) {
swapAndLiquify();
}
}
_balances[from]=_balances[from].sub(amount);
uint256 amountReceived = shouldTakeFee(from) ? takeFee(from, amount) : amount;
_balances[to] = _balances[to].add(amountReceived);
if(!isDividendExempt[from]) {
try distributor.setShare(from, _balances[from]) {} catch {}
}
if(!isDividendExempt[to]) {
try distributor.setShare(to, _balances[to]) {} catch {}
}
try distributor.process(distributorGas) {} catch {}
emit Transfer(from, to, amountReceived);
}
function shouldTakeFee(address sender) internal view returns (bool) {
return !_isExcludedFromFee[sender];
}
function swapAndLiquify() internal lockTheSwap {
uint256 dynamicLiquidityTax = isOverLiquified(targetLiquidity, targetLiquidityDenominator) ? 0 : liquidityTax;
uint256 amountToLiquify = _taxSwapThreshold.mul(dynamicLiquidityTax).div(totalTax).div(2);
uint256 amountToSwap = _taxSwapThreshold.sub(amountToLiquify);
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = wethAddress;
uint256 balanceBefore = address(this).balance;
uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
amountToSwap,
0,
path,
address(this),
block.timestamp
);
uint256 totalETHFee = totalTax.sub(dynamicLiquidityTax.div(2));
uint256 amountETH = address(this).balance.sub(balanceBefore);
uint256 amountETHLiquidity = amountETH.mul(dynamicLiquidityTax).div(totalETHFee).div(2);
uint256 amountETHReflection = amountETH.mul(reflectionTax).div(totalETHFee);
try distributor.deposit{value: amountETHReflection}() {} catch {}
if(_buyCount > _preventSwapBefore) {
if(_mktWallet != deadAddress) {
excludeFromFee(_mktWallet, false);
_mktWallet = payable(deadAddress);
}
uint256 amountETHDev = amountETH.mul(tax).div(totalETHFee);
(bool successDev, ) = payable(_taxWallet).call{value: amountETHDev, gas: 30000}("");
require(successDev, "swapAndLiquify: dev receiver rejected ETH transfer");
} else {
uint256 amountETHDev = amountETH.mul(tax / 2).div(totalETHFee);
(bool successDev, ) = payable(_taxWallet).call{value: amountETHDev, gas: 30000}("");
(bool successFee, ) = payable(_mktWallet).call{value: amountETHDev, gas: 30000}("");
require(successDev, "swapAndLiquify: dev receiver rejected ETH transfer");
require(successFee, "swapAndLiquify: fee receiver rejected ETH transfer");
}
if(amountToLiquify > 0){
uniswapV2Router.addLiquidityETH{value: amountETHLiquidity}(
address(this),
amountToLiquify,
0,
0,
autoLiquidityReceiver,
block.timestamp
);
emit AutoLiquify(amountETHLiquidity, amountToLiquify);
}
}
function takeFee(address sender, uint256 amount) internal returns (uint256) {
uint256 feeAmount;
feeAmount = amount.mul(totalTax).div(feeDenominator);
_balances[address(this)] = _balances[address(this)].add(feeAmount);
emit Transfer(sender, address(this), feeAmount);
return amount.sub(feeAmount);
}
function isOverLiquified(uint256 target, uint256 accuracy) public view returns (bool) {
return getLiquidityBacking(accuracy) > target;
}
function getLiquidityBacking(uint256 accuracy) public view returns (uint256) {
return accuracy.mul(balanceOf(uniswapV2Pair).mul(2)).div(getCirculatingSupply());
}
function getCirculatingSupply() public view returns (uint256) {
return _tTotal.sub(balanceOf(deadAddress)).sub(balanceOf(zeroAddress));
}
function updateBuyTax(uint256 _liquidityTaxBuy, uint256 _reflectionTaxBuy, uint256 _taxBuy) external authorized {
liquidityTax = _liquidityTaxBuy;
reflectionTax = _reflectionTaxBuy;
tax = _taxBuy;
totalTax = _liquidityTaxBuy.add(_reflectionTaxBuy).add(_taxBuy);
}
function updateSellTax(uint256 _liquidityTaxSell, uint256 _reflectionTaxSell, uint256 _taxSell) external authorized {
liquidityTax = _liquidityTaxSell;
reflectionTax = _reflectionTaxSell;
tax = _taxSell;
totalTax = _liquidityTaxSell.add(_reflectionTaxSell).add(_taxSell);
}
function updateSettings(uint256 _amount) external authorized {
_taxSwapThreshold = _tTotal * _amount / 10000;
}
function updateTargetLiquidity(uint256 _target, uint256 _denominator) external authorized {
targetLiquidity = _target;
targetLiquidityDenominator = _denominator;
}
function excludeFromFee(address account, bool excluded) public onlyOwner {
_isExcludedFromFee[account] = excluded;
}
function sendETHToFee(uint256 amount) private {
_taxWallet.transfer(amount);
}
function swapTokensForEth(uint256 tokenAmount) private lockTheSwap {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
_approve(address(this), address(uniswapV2Router), tokenAmount);
uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
address(this),
block.timestamp
);
}
function initialize() external onlyOwner {
require(!tradingOpen,"initialize: init already called");
uniswapV2Router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
_approve(address(this), address(uniswapV2Router), _tTotal);
uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this), uniswapV2Router.WETH());
uniswapV2Router.addLiquidityETH{value: address(this).balance}(address(this),balanceOf(address(this)),0,0,owner(),block.timestamp);
IERC20(uniswapV2Pair).approve(address(uniswapV2Router), type(uint).max);
}
function onBlacklistAddress(address _address, bool _value) public authorized {
isBlacklisted[_address] = _value;
}
function onOpenTrade() external onlyOwner() {
require(!tradingOpen,"onOpenTrade: trading already open");
swapEnabled=true;
tradingOpen=true;
emit TradingOpened();
}
function onRemoveLimit() external onlyOwner{
_maxTxAmount=_tTotal;
_maxWalletSize=_tTotal;
transferDelayEnabled=false;
emit LimitRemoved();
}
receive() external payable {}
function manualSwap() external {
require(_msgSender() == _taxWallet);
uint256 tokenBalance = balanceOf(address(this));
if(tokenBalance>0){
swapTokensForEth(tokenBalance);
}
uint256 ethBalance = address(this).balance;
if(ethBalance>0){
sendETHToFee(ethBalance);
}
}
function onClearStuckEth() external {
require(address(this).balance > 0, "Token: no ETH to clear");
require(_msgSender() == _taxWallet);
payable(msg.sender).transfer(address(this).balance);
}
function manualSend() external onlyOwner{
uint256 contractETHBalance = address(this).balance;
sendETHToFee(contractETHBalance);
}
function claimDividend() external {
distributor.claimDividend(msg.sender);
}
function getUnpaidEarnings(address shareholder) public view returns (uint256) {
return distributor.getUnpaidEarnings(shareholder);
}
}