I've copied a smart contract from other project and trying to do my own from there, I understand solidity but I'm not good enough yet to make a contract from scratch.
So, in this contract I have 6 plans, with values are the amount of days and the daily % of profit. This daily % of profit increases 0.5% per day in all 6 plans.
First plan in the index (0) has 14 days and 8% base daily profit.
When I use the getResults function it retrieves the updated daily profit and makes the calculation to let the user know how much profit will get if investing X amount of tokens, but somehow when I enter a deposit:10 in plan:0 gives me a profit of 0, if I enter deposit:100, plan:0 I get the correct math, it's driving me crazy.
Here is the smart contract (had to put it into a snippet because it breaks the bb code in stackoverflow page):
pragma solidity >=0.4.22 <0.9.0;
contract testing {
using SafeMath for uint256;
uint256 constant public INVEST_MIN_AMOUNT = 10 ether;
uint256[] public REFERRAL_PERCENTS = [60, 40, 20];
uint256 constant public PROJECT_FEE = 100;
uint256 constant public PERCENT_STEP = 5;
uint256 constant public WITHDRAW_FEE = 1000; //In base point
uint256 constant public PERCENTS_DIVIDER = 1000;
uint256 constant public TIME_STEP = 1 days;
uint256 public totalStaked;
uint256 public totalRefBonus;
struct Plan {
uint256 time;
uint256 percent;
}
Plan[] internal plans;
struct Deposit {
uint8 plan;
uint256 percent;
uint256 amount;
uint256 profit;
uint256 start;
uint256 finish;
}
struct User {
Deposit[] deposits;
uint256 checkpoint;
address referrer;
uint256[3] levels;
uint256 bonus;
uint256 totalBonus;
}
mapping (address => User) internal users;
uint256 public startUNIX;
address payable public commissionWallet;
event Newbie(address user);
event NewDeposit(address indexed user, uint8 plan, uint256 percent, uint256 amount, uint256 profit, uint256 start, uint256 finish);
event Withdrawn(address indexed user, uint256 amount);
event RefBonus(address indexed referrer, address indexed referral, uint256 indexed level, uint256 amount);
event FeePayed(address indexed user, uint256 totalAmount);
constructor(address payable wallet, uint256 startDate) public {
require(!isContract(wallet));
require(startDate > 0);
commissionWallet = wallet;
startUNIX = startDate;
plans.push(Plan(14, 80));
plans.push(Plan(21, 65));
plans.push(Plan(28, 50));
plans.push(Plan(14, 80));
plans.push(Plan(21, 65));
plans.push(Plan(28, 50));
}
function invest(address referrer, uint8 plan) public payable {
require(msg.value >= INVEST_MIN_AMOUNT);
require(plan < 6, "Invalid plan");
uint256 fee = msg.value.mul(PROJECT_FEE).div(PERCENTS_DIVIDER);
commissionWallet.transfer(fee);
emit FeePayed(msg.sender, fee);
User storage user = users[msg.sender];
if (user.referrer == address(0)) {
if (users[referrer].deposits.length > 0 && referrer != msg.sender) {
user.referrer = referrer;
}
address upline = user.referrer;
for (uint256 i = 0; i < 3; i++) {
if (upline != address(0)) {
users[upline].levels[i] = users[upline].levels[i].add(1);
upline = users[upline].referrer;
} else break;
}
}
if (user.referrer != address(0)) {
address upline = user.referrer;
for (uint256 i = 0; i < 3; i++) {
if (upline != address(0)) {
uint256 amount = msg.value.mul(REFERRAL_PERCENTS[i]).div(PERCENTS_DIVIDER);
users[upline].bonus = users[upline].bonus.add(amount);
users[upline].totalBonus = users[upline].totalBonus.add(amount);
emit RefBonus(upline, msg.sender, i, amount);
upline = users[upline].referrer;
} else break;
}
}
if (user.deposits.length == 0) {
user.checkpoint = block.timestamp;
emit Newbie(msg.sender);
}
(uint256 percent, uint256 profit, uint256 finish) = getResult(plan, msg.value);
user.deposits.push(Deposit(plan, percent, msg.value, profit, block.timestamp, finish));
totalStaked = totalStaked.add(msg.value);
emit NewDeposit(msg.sender, plan, percent, msg.value, profit, block.timestamp, finish);
}
function withdraw() public {
User storage user = users[msg.sender];
uint256 totalAmount = getUserDividends(msg.sender);
uint256 fees = totalAmount.mul(WITHDRAW_FEE).div(10000);
totalAmount = totalAmount.sub(fees);
uint256 referralBonus = getUserReferralBonus(msg.sender);
if (referralBonus > 0) {
user.bonus = 0;
totalAmount = totalAmount.add(referralBonus);
}
require(totalAmount > 0, "User has no dividends");
uint256 contractBalance = address(this).balance;
if (contractBalance < totalAmount) {
totalAmount = contractBalance;
}
user.checkpoint = block.timestamp;
msg.sender.transfer(totalAmount);
emit Withdrawn(msg.sender, totalAmount);
}
function getContractBalance() public view returns (uint256) {
return address(this).balance;
}
function getPlanInfo(uint8 plan) public view returns(uint256 time, uint256 percent) {
time = plans[plan].time;
percent = plans[plan].percent;
}
function getPercent(uint8 plan) public view returns (uint256) {
if (block.timestamp > startUNIX) {
return plans[plan].percent.add(PERCENT_STEP.mul(block.timestamp.sub(startUNIX)).div(TIME_STEP));
} else {
return plans[plan].percent;
}
}
function getResult(uint8 plan, uint256 deposit) public view returns (uint256 percent, uint256 profit, uint256 finish) {
percent = getPercent(plan);
if (plan < 3) {
profit = deposit.mul(percent).div(PERCENTS_DIVIDER).mul(plans[plan].time);
} else if (plan < 6) {
for (uint256 i = 0; i < plans[plan].time; i++) {
profit = profit.add((deposit.add(profit)).mul(percent).div(PERCENTS_DIVIDER));
}
}
finish = block.timestamp.add(plans[plan].time.mul(TIME_STEP));
}
function getUserDividends(address userAddress) public view returns (uint256) {
User storage user = users[userAddress];
uint256 totalAmount;
for (uint256 i = 0; i < user.deposits.length; i++) {
if (user.checkpoint < user.deposits[i].finish) {
if (user.deposits[i].plan < 3) {
uint256 share = user.deposits[i].amount.mul(user.deposits[i].percent).div(PERCENTS_DIVIDER);
uint256 from = user.deposits[i].start > user.checkpoint ? user.deposits[i].start : user.checkpoint;
uint256 to = user.deposits[i].finish < block.timestamp ? user.deposits[i].finish : block.timestamp;
if (from < to) {
totalAmount = totalAmount.add(share.mul(to.sub(from)).div(TIME_STEP));
}
} else if (block.timestamp > user.deposits[i].finish) {
totalAmount = totalAmount.add(user.deposits[i].profit);
}
}
}
return totalAmount;
}
function getUserCheckpoint(address userAddress) public view returns(uint256) {
return users[userAddress].checkpoint;
}
function getUserReferrer(address userAddress) public view returns(address) {
return users[userAddress].referrer;
}
function getUserDownlineCount(address userAddress) public view returns(uint256, uint256, uint256) {
return (users[userAddress].levels[0], users[userAddress].levels[1], users[userAddress].levels[2]);
}
function getUserReferralBonus(address userAddress) public view returns(uint256) {
return users[userAddress].bonus;
}
function getUserReferralTotalBonus(address userAddress) public view returns(uint256) {
return users[userAddress].totalBonus;
}
function getUserReferralWithdrawn(address userAddress) public view returns(uint256) {
return users[userAddress].totalBonus.sub(users[userAddress].bonus);
}
function getUserAvailable(address userAddress) public view returns(uint256) {
return getUserReferralBonus(userAddress).add(getUserDividends(userAddress));
}
function getUserAmountOfDeposits(address userAddress) public view returns(uint256) {
return users[userAddress].deposits.length;
}
function getUserTotalDeposits(address userAddress) public view returns(uint256 amount) {
for (uint256 i = 0; i < users[userAddress].deposits.length; i++) {
amount = amount.add(users[userAddress].deposits[i].amount);
}
}
function getUserDepositInfo(address userAddress, uint256 index) public view returns(uint8 plan, uint256 percent, uint256 amount, uint256 profit, uint256 start, uint256 finish) {
User storage user = users[userAddress];
plan = user.deposits[index].plan;
percent = user.deposits[index].percent;
amount = user.deposits[index].amount;
profit = user.deposits[index].profit;
start = user.deposits[index].start;
finish = user.deposits[index].finish;
}
function isContract(address addr) internal view returns (bool) {
uint size;
assembly { size := extcodesize(addr) }
return size > 0;
}
}
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) {
require(b <= a, "SafeMath: subtraction overflow");
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) {
require(b > 0, "SafeMath: division by zero");
uint256 c = a / b;
return c;
}
}
I think I found the issue. Since we are only handling integers there are no double type of variables, in the division it was rounding to 0, then when multiplied still being 0.
I've changed the div to be last part of the operation.
Replace this:
profit = deposit.mul(percent).div(PERCENTS_DIVIDER).mul(plans[plan].time);
to this:
profit = deposit.mul(percent).mul(plans[plan].time).div(PERCENTS_DIVIDER);
Related
I created a basic contract for crowdfunding. But cannot figure out how to create a withdraw function.
Withdraw function will transfer a campaign's collected funds to the campaign's owner. This is my full crowdfunding contract:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
contract CrowdFunding {
event testConditon(
uint256 deadline,
uint256 currentTimeInMs,
uint256 diff,
bool condition
);
struct Campaign {
address payable owner;
string title;
string description;
uint256 target;
uint256 deadline;
uint256 amountCollected;
string image;
address[] donators;
uint256[] donations;
}
mapping(uint256 => Campaign) public campaigns;
uint256 public numberOfCampaigns = 0;
function createCampaign(
address _owner,
string memory _title,
string memory _description,
uint256 _target,
uint256 _deadline,
string memory _image
) public returns (uint256) {
Campaign storage campaign = campaigns[numberOfCampaigns];
uint256 currentTimeInMs = block.timestamp * 1000;
emit testConditon(
_deadline,
currentTimeInMs,
_deadline - currentTimeInMs,
_deadline > currentTimeInMs
);
require(
_deadline > currentTimeInMs,
"The deadline must be in the future"
);
campaign.owner = payable(_owner);
campaign.title = _title;
campaign.description = _description;
campaign.target = _target;
campaign.deadline = _deadline;
campaign.image = _image;
campaign.amountCollected = 0;
numberOfCampaigns++;
return numberOfCampaigns - 1;
}
function donateToCampaign(uint256 _id) public payable {
uint256 amount = msg.value;
Campaign storage campaign = campaigns[_id];
campaign.donators.push(msg.sender);
campaign.donations.push(amount);
(bool sent, ) = payable(campaign.owner).call{value: amount}("");
if (sent) {
campaign.amountCollected += amount;
}
}
function getDonators(uint256 _id)
public
view
returns (address[] memory, uint256[] memory)
{
return (campaigns[_id].donators, campaigns[_id].donations);
}
function getCampaigns() public view returns (Campaign[] memory) {
Campaign[] memory allCampaigns = new Campaign[](numberOfCampaigns);
for (uint256 i = 0; i < numberOfCampaigns; i++) {
Campaign storage item = campaigns[i];
allCampaigns[i] = item;
}
return allCampaigns;
}
function withdraw(uint256 _id) public {
Campaign storage campaign = campaigns[_id];
require(
campaign.amountCollected >= campaign.target,
"The campaign has not reached its target"
);
//deadline has passed
// require(
// campaign.deadline < block.timestamp * 1000,
// "The deadline has not passed yet"
// );
require(
campaign.owner == msg.sender,
"Only the owner of the campaign can withdraw the funds"
);
campaign.owner.transfer(campaign.amountCollected);
campaign.amountCollected = 0;
}
}
I have no idea how to solve this issue.
Looks like you are missing the payable keyword to trigger the token transfer. Try this:
function withdraw(uint256 _id) public {
Campaign storage campaign = campaigns[_id];
(bool success, ) = payable(campaign.owner).call{value: campaign.amountCollected}("");
require(success, "Withdrawal failure");
campaign.amountCollected = 0;
}
Warning: this function and your function are having a reentrency vulnerability.
Trying to merge 2 smart contracts and having some issues. I just want to move my blacklist function from an old contract to my new one. I'll include the line of code. I need adding as I've done the rest just can't find where to put it. In the old contract it was under the _transfer function however my new code doesn't have this exact function.
I'll include the full contract below. the line of code I need adding to make the blacklist function work is:
require(!_isBlackList[from] && !_isBlackList[to],"You are black listed by Owner");
And it needs to sit somewhere in the following code:
// SPDX-License-Identifier: unlicensed
pragma solidity ^0.8.6;
/**
* BEP20 standard interface
*/
interface IBEP20 {
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);
}
abstract contract Ownable {
address internal owner;
address private _previousOwner;
uint256 private _lockTime;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address _owner) {
owner =_owner;
}
modifier onlyOwner() {
require(isOwner(msg.sender), "!OWNER"); _;
}
function isOwner(address account) public view returns (bool) {
return account == owner;
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
function getUnlockTime() public view returns (uint256) {
return _lockTime;
}
function Ownershiplock(uint256 time) public virtual onlyOwner {
_previousOwner = owner;
owner = address(0);
_lockTime = block.timestamp + time;
emit OwnershipTransferred(owner, address(0));
}
function Ownershipunlock() public virtual {
require(_previousOwner == msg.sender, "You don't have permission to unlock");
require(block.timestamp > _lockTime , "Contract is locked");
emit OwnershipTransferred(owner, _previousOwner);
owner = _previousOwner;
}
}
/**
* Router Interfaces
*/
interface IDEXFactory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
interface IDEXRouter {
function factory() external pure returns (address);
function WWBNB() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityWBNB(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountWBNBMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountWBNB, uint liquidity);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactWBNBForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForWBNBSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
/**
* Contract Code
*/
contract ZelBNB is IBEP20, Ownable {
address WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
address DEAD = 0x000000000000000000000000000000000000dEaD;
address ZERO = 0x0000000000000000000000000000000000000000;
string constant _name = "ZelBNB"; //
string constant _symbol = "ZBNB"; //
uint8 constant _decimals = 9;
uint256 _totalSupply = 1 * 10**6 * 10**_decimals;
mapping (address => uint256) _balances;
mapping (address => mapping (address => uint256)) _allowances;
mapping (address => bool) public isFeeExempt;
mapping (address => bool) public isTxLimitExempt;
mapping (address => bool) private _isBlackList;
// Detailed Fees
uint256 public liquidityFee;
uint256 public devFee;
uint256 public marketingFee;
uint256 public buybackFee;
uint256 public totalFee;
uint256 public BuyliquidityFee = 3;
uint256 public BuydevFee = 0;
uint256 public BuymarketingFee = 5;
uint256 public BuybuybackFee = 2;
uint256 public BuytotalFee = BuyliquidityFee + BuydevFee + BuymarketingFee + BuybuybackFee;
uint256 public SellliquidityFee = 3;
uint256 public SelldevFee = 0;
uint256 public SellmarketingFee = 5;
uint256 public SellbuybackFee = 2;
uint256 public SelltotalFee = SellliquidityFee + SelldevFee + SellmarketingFee + SellbuybackFee;
// Max wallet & Transaction
uint256 public _maxBuyTxAmount = _totalSupply / (100) * (2); // 1%
uint256 public _maxSellTxAmount = _totalSupply / (100) * (2); // 1%
uint256 public _maxWalletToken = _totalSupply / (100) * (2); // 1%
// Fees receivers
address public autoLiquidityReceiver = 0xF3902ad7681324F723CE91760B252B4bDf594517;
address public marketingFeeReceiver = 0x9d01b64acdbef3E0DB64B2f4bFC092a68218b2F3;
address public devFeeReceiver = 0xF3902ad7681324F723CE91760B252B4bDf594517;
address public buybackFeeReceiver = 0x9d01b64acdbef3E0DB64B2f4bFC092a68218b2F3;
IDEXRouter public router;
address public pair;
bool public swapEnabled = true;
uint256 public swapThreshold = _totalSupply / 1000 * 1; // 0.1%
uint256 public maxSwapSize = _totalSupply / 100 * 1; //1%
uint256 public tokensToSell;
bool inSwap;
modifier swapping() { inSwap = true; _; inSwap = false; }
constructor () Ownable(msg.sender) {
router = IDEXRouter(0xD99D1c33F9fC3444f8101754aBC46c52416550D1);
pair = IDEXFactory(router.factory()).createPair(WBNB, address(this));
_allowances[address(this)][address(router)] = type(uint256).max;
isFeeExempt[msg.sender] = true;
isTxLimitExempt[msg.sender] = true;
_balances[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
receive() external payable { }
function totalSupply() external view override returns (uint256) { return _totalSupply; }
function decimals() external pure override returns (uint8) { return _decimals; }
function symbol() external pure override returns (string memory) { return _symbol; }
function name() external pure override returns (string memory) { return _name; }
function getOwner() external view override returns (address) { return owner; }
function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
function allowance(address holder, address spender) external view override returns (uint256) { return _allowances[holder][spender]; }
function approve(address spender, uint256 amount) public override returns (bool) {
_allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function approveMax(address spender) external returns (bool) {
return approve(spender, type(uint256).max);
}
function transfer(address recipient, uint256 amount) external override returns (bool) {
return _transferFrom(msg.sender, recipient, amount);
}
function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) {
if(_allowances[sender][msg.sender] != type(uint256).max){
_allowances[sender][msg.sender] = _allowances[sender][msg.sender] - amount;
}
return _transferFrom(sender, recipient, amount);
}
function _transferFrom(address sender, address recipient, uint256 amount) internal returns (bool) {
if(inSwap){ return _basicTransfer(sender, recipient, amount); }
if(sender == pair){
buyFees();
}
if(recipient == pair){
sellFees();
}
if (sender != owner && recipient != address(this) && recipient != address(DEAD) && recipient != pair || isTxLimitExempt[recipient]){
uint256 heldTokens = balanceOf(recipient);
require((heldTokens + amount) <= _maxWalletToken,"Total Holding is currently limited, you can not buy that much.");
}
// Checks max transaction limit
if(sender == pair){
require(amount <= _maxBuyTxAmount || isTxLimitExempt[recipient], "TX Limit Exceeded");
}
if(recipient == pair){
require(amount <= _maxSellTxAmount || isTxLimitExempt[sender], "TX Limit Exceeded");
}
//Exchange tokens
if(shouldSwapBack()){ swapBack(); }
_balances[sender] = _balances[sender] - amount;
uint256 amountReceived = shouldTakeFee(sender) ? takeFee(recipient, amount) : amount;
_balances[recipient] = _balances[recipient] + amountReceived;
emit Transfer(sender, recipient, amountReceived);
return true;
}
function _basicTransfer(address sender, address recipient, uint256 amount) internal returns (bool) {
_balances[sender] = _balances[sender] - amount;
_balances[recipient] = _balances[recipient] + (amount);
emit Transfer(sender, recipient, amount);
return true;
}
// Internal Functions
function buyFees() internal{
liquidityFee = BuyliquidityFee;
devFee = BuydevFee;
marketingFee = BuymarketingFee;
buybackFee = BuybuybackFee;
totalFee = BuytotalFee;
}
function sellFees() internal{
liquidityFee = SellliquidityFee;
devFee = SelldevFee;
marketingFee = SellmarketingFee;
buybackFee = SellbuybackFee;
totalFee = SelltotalFee;
}
function shouldTakeFee(address sender) internal view returns (bool) {
return !isFeeExempt[sender];
}
function takeFee(address sender, uint256 amount) internal returns (uint256) {
uint256 feeAmount = amount / 100 * (totalFee);
_balances[address(this)] = _balances[address(this)] + (feeAmount);
emit Transfer(sender, address(this), feeAmount);
return amount - (feeAmount);
}
function shouldSwapBack() internal view returns (bool) {
return msg.sender != pair
&& !inSwap
&& swapEnabled
&& _balances[address(this)] >= swapThreshold;
}
function swapBack() internal swapping {
uint256 contractTokenBalance = balanceOf(address(this));
if(contractTokenBalance >= maxSwapSize){
tokensToSell = maxSwapSize;
}
else{
tokensToSell = contractTokenBalance;
}
uint256 amountToLiquify = tokensToSell / (totalFee) * (liquidityFee) / (2);
uint256 amountToSwap = tokensToSell - (amountToLiquify);
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = WBNB;
uint256 balanceBefore = address(this).balance;
router.swapExactTokensForWBNBSupportingFeeOnTransferTokens(
amountToSwap,
0,
path,
address(this),
block.timestamp
);
uint256 amountBNB = address(this).balance - (balanceBefore);
uint256 totalBNBFee = totalFee - (liquidityFee / (2));
uint256 amountBNBLiquidity = amountBNB * (liquidityFee) / (totalBNBFee) / (2);
uint256 amountBNBbuyback = amountBNB * (buybackFee) / (totalBNBFee);
uint256 amountBNBMarketing = amountBNB * (marketingFee) / (totalBNBFee);
uint256 amountBNBDev = amountBNB - amountBNBLiquidity - amountBNBbuyback - amountBNBMarketing;
(bool MarketingSuccess,) = payable(marketingFeeReceiver).call{value: amountBNBMarketing, gas: 500}("");
require(MarketingSuccess, "receiver rejected WBNB transfer");
(bool buybackSuccess,) = payable(buybackFeeReceiver).call{value: amountBNBbuyback, gas: 500}("");
require(buybackSuccess, "receiver rejected WBNB transfer");
(bool devSuccess,) = payable(devFeeReceiver).call{value: amountBNBDev, gas: 500}("");
require(devSuccess, "receiver rejected WBNB transfer");
addLiquidity(amountToLiquify, amountBNBLiquidity);
}
function addLiquidity(uint256 tokenAmount, uint256 BNBAmount) private {
if(tokenAmount > 0){
router.addLiquidityWBNB{value: BNBAmount}(
address(this),
tokenAmount,
0,
0,
autoLiquidityReceiver,
block.timestamp
);
emit AutoLiquify(BNBAmount, tokenAmount);
}
}
// External Functions
function checkSwapThreshold() external view returns (uint256) {
return swapThreshold;
}
function checkMaxWalletToken() external view returns (uint256) {
return _maxWalletToken;
}
function checkMaxBuyTxAmount() external view returns (uint256) {
return _maxBuyTxAmount;
}
function checkMaxSellTxAmount() external view returns (uint256) {
return _maxSellTxAmount;
}
function isNotInSwap() external view returns (bool) {
return !inSwap;
}
// Only Owner allowed
function setBuyFees(uint256 _liquidityFee, uint256 _buybackFee, uint256 _marketingFee, uint256 _devFee) external onlyOwner {
BuyliquidityFee = _liquidityFee;
BuybuybackFee = _buybackFee;
BuymarketingFee = _marketingFee;
BuydevFee = _devFee;
BuytotalFee = _liquidityFee + (_buybackFee) + (_marketingFee) + (_devFee);
}
function setSellFees(uint256 _liquidityFee, uint256 _buybackFee, uint256 _marketingFee, uint256 _devFee) external onlyOwner {
SellliquidityFee = _liquidityFee;
SellbuybackFee = _buybackFee;
SellmarketingFee = _marketingFee;
SelldevFee = _devFee;
SelltotalFee = _liquidityFee + (_buybackFee) + (_marketingFee) + (_devFee);
}
function setFeeReceivers(address _autoLiquidityReceiver, address _marketingFeeReceiver, address _buybackFeeReceiver, address _devFeeReceiver) external onlyOwner {
autoLiquidityReceiver = _autoLiquidityReceiver;
marketingFeeReceiver = _marketingFeeReceiver;
buybackFeeReceiver = _buybackFeeReceiver;
devFeeReceiver = _devFeeReceiver;
}
function setSwapBackSettings(bool _enabled, uint256 _percentage_min_base10000, uint256 _percentage_max_base10000) external onlyOwner {
swapEnabled = _enabled;
swapThreshold = _totalSupply / (10000) * (_percentage_min_base10000);
maxSwapSize = _totalSupply / (10000) * (_percentage_max_base10000);
}
function setIsFeeExempt(address holder, bool exempt) external onlyOwner {
isFeeExempt[holder] = exempt;
}
function setIsTxLimitExempt(address holder, bool exempt) external onlyOwner {
isTxLimitExempt[holder] = exempt;
}
function setMaxWalletPercent_base1000(uint256 maxWallPercent_base1000) external onlyOwner {
_maxWalletToken = _totalSupply / (1000) * (maxWallPercent_base1000);
}
function setMaxBuyTxPercent_base1000(uint256 maxBuyTXPercentage_base1000) external onlyOwner {
_maxBuyTxAmount = _totalSupply / (1000) * (maxBuyTXPercentage_base1000);
}
function setMaxSellTxPercent_base1000(uint256 maxSellTXPercentage_base1000) external onlyOwner {
_maxSellTxAmount = _totalSupply / (1000) * (maxSellTXPercentage_base1000);
}
function isBlackList(address Account)external view returns(bool){
return _isBlackList[Account];
}
function SetBlackListAccountStatus(address Account, bool status)external onlyOwner(){
_isBlackList[Account] = status;
}
// Stuck Balances Functions
function rescueToken(address tokenAddress, uint256 tokens) public onlyOwner returns (bool success) {
return IBEP20(tokenAddress).transfer(msg.sender, tokens);
}
function clearStuckBalance(uint256 amountPercentage) external onlyOwner {
uint256 amountBNB = address(this).balance;
payable(msg.sender).transfer(amountBNB * amountPercentage / 100);
}
event AutoLiquify(uint256 amountBNB, uint256 amountTokens);
}
any help would be great! thanks
GM there!
_transfer is an internal function provided by the ERC20 Openzeppelin library, you can override it in the contract and add your lines in the contract like this
function _transfer(address sender, address recipient, uint256 amount) internal virtual override {
require(!_isBlackList[from] && !_isBlackList[to],"You are black listed by Owner");
super._transfer(sender, recipient, amount);
}
Hope this helps, Cheers~
Recently I deployed my bep20 contract, everything was fine then when I was testing it on testnet and try to buy my token with different address in my metamask, for the first two transaction everything was good but after that I couldn't buy/sell my token anymore, If someone has a solution to fix that please let me know, btw, for the test on pancakeswap test net I am using this router address:0x9Ac64Cc6e4415144C455BD8E4837Fea55603e5c3 and even this : 0xD99D1c33F9fC3444f8101754aBC46c52416550D1.
Thank you in advance
here the contract:
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* SAFEMATH LIBRARY
*/
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
interface IBEP20 {
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);
}
abstract contract Auth {
address internal owner;
mapping (address => bool) internal authorizations;
constructor(address _owner) {
owner = _owner;
authorizations[_owner] = true;
}
/**
* Function modifier to require caller to be contract owner
*/
modifier onlyOwner() {
require(isOwner(msg.sender), "!OWNER"); _;
}
/**
* Function modifier to require caller to be authorized
*/
modifier authorized() {
require(isAuthorized(msg.sender), "!AUTHORIZED"); _;
}
/**
* Authorize address. Owner only
*/
function authorize(address adr) public onlyOwner {
authorizations[adr] = true;
}
/**
* Remove address' authorization. Owner only
*/
function unauthorize(address adr) public onlyOwner {
authorizations[adr] = false;
}
/**
* Check if address is owner
*/
function isOwner(address account) public view returns (bool) {
return account == owner;
}
/**
* Return address' authorization status
*/
function isAuthorized(address adr) public view returns (bool) {
return authorizations[adr];
}
/**
* Transfer ownership to new address. Caller must be owner. Leaves old owner authorized
*/
function transferOwnership(address payable adr) public onlyOwner {
owner = adr;
authorizations[adr] = true;
emit OwnershipTransferred(adr);
}
event OwnershipTransferred(address owner);
}
interface IDEXFactory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
interface IDEXRouter {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
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;
}
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;
}
IBEP20 BUSD = IBEP20(0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56);
address WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
IDEXRouter router;
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 = 1 hours;
uint256 public minDistribution = 1 * (10 ** 18);
uint256 currentIndex;
bool initialized;
modifier initialization() {
require(!initialized);
_;
initialized = true;
}
modifier onlyToken() {
require(msg.sender == _token); _;
}
constructor (address _router) {
router = _router != address(0)
? IDEXRouter(_router)
//: IDEXRouter(0x10ED43C718714eb63d5aA57B78B54704E256024E);
: IDEXRouter(0x9Ac64Cc6e4415144C455BD8E4837Fea55603e5c3);
_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 = BUSD.balanceOf(address(this));
address[] memory path = new address[](2);
path[0] = WBNB;
path[1] = address(BUSD);
router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(
0,
path,
address(this),
block.timestamp
);
uint256 amount = BUSD.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);
BUSD.transfer(shareholder, amount);
shareholderClaims[shareholder] = block.timestamp;
shares[shareholder].totalRealised = shares[shareholder].totalRealised.add(amount);
shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
}
}
function claimDividend() external {
distributeDividend(msg.sender);
}
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 TestMyToken is IBEP20, Auth {
using SafeMath for uint256;
uint256 public constant MASK = type(uint128).max;
address BUSD = 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56;
address public WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
address DEAD = 0x000000000000000000000000000000000000dEaD;
address ZERO = 0x0000000000000000000000000000000000000000;
address DEAD_NON_CHECKSUM = 0x000000000000000000000000000000000000dEaD;
string constant _name = "TestmyToken";
string constant _symbol = "TMT";
uint8 constant _decimals = 9;
uint256 _totalSupply = 1_000_000_000_000_000 * (10 ** _decimals);
uint256 public _maxTxAmount = _totalSupply.div(400); // 0.25%
mapping (address => uint256) _balances;
mapping (address => mapping (address => uint256)) _allowances;
mapping (address => bool) isFeeExempt;
mapping (address => bool) isTxLimitExempt;
mapping (address => bool) isDividendExempt;
uint256 liquidityFee = 200;
uint256 buybackFee = 300;
uint256 reflectionFee = 800;
uint256 marketingFee = 100;
uint256 totalFee = 1400;
uint256 feeDenominator = 10000;
address public autoLiquidityReceiver;
address public marketingFeeReceiver;
uint256 targetLiquidity = 25;
uint256 targetLiquidityDenominator = 100;
IDEXRouter public router;
address public pair;
uint256 public launchedAt;
uint256 public launchedAtTimestamp;
uint256 buybackMultiplierNumerator = 200;
uint256 buybackMultiplierDenominator = 100;
uint256 buybackMultiplierTriggeredAt;
uint256 buybackMultiplierLength = 30 minutes;
bool public autoBuybackEnabled = false;
mapping (address => bool) buyBacker;
uint256 autoBuybackCap;
uint256 autoBuybackAccumulator;
uint256 autoBuybackAmount;
uint256 autoBuybackBlockPeriod;
uint256 autoBuybackBlockLast;
DividendDistributor distributor;
address public distributorAddress;
uint256 distributorGas = 500000;
bool public swapEnabled = true;
uint256 public swapThreshold = _totalSupply / 2000; // 0.005%
bool inSwap;
modifier swapping() { inSwap = true; _; inSwap = false; }
constructor (
address _dexRouter
) Auth(msg.sender) {
router = IDEXRouter(_dexRouter);
pair = IDEXFactory(router.factory()).createPair(WBNB, address(this));
_allowances[address(this)][address(router)] = _totalSupply;
WBNB = router.WETH();
distributor = new DividendDistributor(_dexRouter);
distributorAddress = address(distributor);
isFeeExempt[msg.sender] = true;
isTxLimitExempt[msg.sender] = true;
isDividendExempt[pair] = true;
isDividendExempt[address(this)] = true;
isDividendExempt[DEAD] = true;
buyBacker[msg.sender] = true;
autoLiquidityReceiver = msg.sender;
marketingFeeReceiver = msg.sender;
approve(_dexRouter, _totalSupply);
approve(address(pair), _totalSupply);
_balances[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
receive() external payable { }
function totalSupply() external view override returns (uint256) { return _totalSupply; }
function decimals() external pure override returns (uint8) { return _decimals; }
function symbol() external pure override returns (string memory) { return _symbol; }
function name() external pure override returns (string memory) { return _name; }
function getOwner() external view override returns (address) { return owner; }
modifier onlyBuybacker() { require(buyBacker[msg.sender] == true, ""); _; }
function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
function allowance(address holder, address spender) external view override returns (uint256) { return _allowances[holder][spender]; }
function approve(address spender, uint256 amount) public override returns (bool) {
_allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function approveMax(address spender) external returns (bool) {
return approve(spender, _totalSupply);
}
function transfer(address recipient, uint256 amount) external override returns (bool) {
return _transferFrom(msg.sender, recipient, amount);
}
function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) {
if(_allowances[sender][msg.sender] != _totalSupply){
_allowances[sender][msg.sender] = _allowances[sender][msg.sender].sub(amount, "Insufficient Allowance");
}
return _transferFrom(sender, recipient, amount);
}
function _transferFrom(address sender, address recipient, uint256 amount) internal returns (bool) {
if(inSwap){ return _basicTransfer(sender, recipient, amount); }
checkTxLimit(sender, amount);
//
if(shouldSwapBack()){ swapBack(); }
if(shouldAutoBuyback()){ triggerAutoBuyback(); }
// if(!launched() && recipient == pair){ require(_balances[sender] > 0); launch(); }
_balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
uint256 amountReceived = shouldTakeFee(sender) ? takeFee(sender, recipient, amount) : amount;
_balances[recipient] = _balances[recipient].add(amountReceived);
if(!isDividendExempt[sender]){ try distributor.setShare(sender, _balances[sender]) {} catch {} }
if(!isDividendExempt[recipient]){ try distributor.setShare(recipient, _balances[recipient]) {} catch {} }
try distributor.process(distributorGas) {} catch {}
emit Transfer(sender, recipient, amountReceived);
return true;
}
function _basicTransfer(address sender, address recipient, uint256 amount) internal returns (bool) {
_balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
_balances[recipient] = _balances[recipient].add(amount);
// emit Transfer(sender, recipient, amount);
return true;
}
function checkTxLimit(address sender, uint256 amount) internal view {
require(amount <= _maxTxAmount || isTxLimitExempt[sender], "TX Limit Exceeded");
}
function shouldTakeFee(address sender) internal view returns (bool) {
return !isFeeExempt[sender];
}
function getTotalFee(bool selling) public view returns (uint256) {
if(launchedAt + 1 >= block.number){ return feeDenominator.sub(1); }
if(selling){ return getMultipliedFee(); }
return totalFee;
}
function getMultipliedFee() public view returns (uint256) {
if (launchedAtTimestamp + 1 days > block.timestamp) {
return totalFee.mul(18000).div(feeDenominator);
} else if (buybackMultiplierTriggeredAt.add(buybackMultiplierLength) > block.timestamp) {
uint256 remainingTime = buybackMultiplierTriggeredAt.add(buybackMultiplierLength).sub(block.timestamp);
uint256 feeIncrease = totalFee.mul(buybackMultiplierNumerator).div(buybackMultiplierDenominator).sub(totalFee);
return totalFee.add(feeIncrease.mul(remainingTime).div(buybackMultiplierLength));
}
return totalFee;
}
function takeFee(address sender, address receiver, uint256 amount) internal returns (uint256) {
uint256 feeAmount = amount.mul(getTotalFee(receiver == pair)).div(feeDenominator);
_balances[address(this)] = _balances[address(this)].add(feeAmount);
emit Transfer(sender, address(this), feeAmount);
return amount.sub(feeAmount);
}
function shouldSwapBack() internal view returns (bool) {
return msg.sender != pair
&& !inSwap
&& swapEnabled
&& _balances[address(this)] >= swapThreshold;
}
function swapBack() internal swapping {
uint256 dynamicLiquidityFee = isOverLiquified(targetLiquidity, targetLiquidityDenominator) ? 0 : liquidityFee;
uint256 amountToLiquify = swapThreshold.mul(dynamicLiquidityFee).div(totalFee).div(2);
uint256 amountToSwap = swapThreshold.sub(amountToLiquify);
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = WBNB;
uint256 balanceBefore = address(this).balance;
router.swapExactTokensForETHSupportingFeeOnTransferTokens(
amountToSwap,
0,
path,
address(this),
block.timestamp
);
uint256 amountBNB = address(this).balance.sub(balanceBefore);
uint256 totalBNBFee = totalFee.sub(dynamicLiquidityFee.div(2));
uint256 amountBNBLiquidity = amountBNB.mul(dynamicLiquidityFee).div(totalBNBFee).div(2);
uint256 amountBNBReflection = amountBNB.mul(reflectionFee).div(totalBNBFee);
uint256 amountBNBMarketing = amountBNB.mul(marketingFee).div(totalBNBFee);
try distributor.deposit{value: amountBNBReflection}() {} catch {}
payable(marketingFeeReceiver).transfer(amountBNBMarketing);
if(amountToLiquify > 0){
router.addLiquidityETH{value: amountBNBLiquidity}(
address(this),
amountToLiquify,
0,
0,
autoLiquidityReceiver,
block.timestamp
);
emit AutoLiquify(amountBNBLiquidity, amountToLiquify);
}
}
function shouldAutoBuyback() internal view returns (bool) {
return msg.sender != pair
&& !inSwap
&& autoBuybackEnabled
&& autoBuybackBlockLast + autoBuybackBlockPeriod <= block.number // After N blocks from last buyback
&& address(this).balance >= autoBuybackAmount;
}
function triggerZeusBuyback(uint256 amount, bool triggerBuybackMultiplier) external authorized {
buyTokens(amount, DEAD);
if(triggerBuybackMultiplier){
buybackMultiplierTriggeredAt = block.timestamp;
emit BuybackMultiplierActive(buybackMultiplierLength);
}
}
function clearBuybackMultiplier() external authorized {
buybackMultiplierTriggeredAt = 0;
}
function triggerAutoBuyback() internal {
buyTokens(autoBuybackAmount, DEAD);
autoBuybackBlockLast = block.number;
autoBuybackAccumulator = autoBuybackAccumulator.add(autoBuybackAmount);
if(autoBuybackAccumulator > autoBuybackCap){ autoBuybackEnabled = false; }
}
function buyTokens(uint256 amount, address to) internal swapping {
address[] memory path = new address[](2);
path[0] = WBNB;
path[1] = address(this);
router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amount}(
0,
path,
to,
block.timestamp
);
}
function setAutoBuybackSettings(bool _enabled, uint256 _cap, uint256 _amount, uint256 _period) external authorized {
autoBuybackEnabled = _enabled;
autoBuybackCap = _cap;
autoBuybackAccumulator = 0;
autoBuybackAmount = _amount;
autoBuybackBlockPeriod = _period;
autoBuybackBlockLast = block.number;
}
function setBuybackMultiplierSettings(uint256 numerator, uint256 denominator, uint256 length) external authorized {
require(numerator / denominator <= 2 && numerator > denominator);
buybackMultiplierNumerator = numerator;
buybackMultiplierDenominator = denominator;
buybackMultiplierLength = length;
}
function launched() internal view returns (bool) {
return launchedAt != 0;
}
function launch() public authorized {
require(launchedAt == 0, "Already launched boi");
launchedAt = block.number;
launchedAtTimestamp = block.timestamp;
}
function setTxLimit(uint256 amount) external authorized {
require(amount >= _totalSupply / 1000);
_maxTxAmount = amount;
}
function setIsDividendExempt(address holder, bool exempt) external authorized {
require(holder != address(this) && holder != pair);
isDividendExempt[holder] = exempt;
if(exempt){
distributor.setShare(holder, 0);
}else{
distributor.setShare(holder, _balances[holder]);
}
}
function setIsFeeExempt(address holder, bool exempt) external authorized {
isFeeExempt[holder] = exempt;
}
function setIsTxLimitExempt(address holder, bool exempt) external authorized {
isTxLimitExempt[holder] = exempt;
}
function setFees(uint256 _liquidityFee, uint256 _buybackFee, uint256 _reflectionFee, uint256 _marketingFee, uint256 _feeDenominator) external authorized {
liquidityFee = _liquidityFee;
buybackFee = _buybackFee;
reflectionFee = _reflectionFee;
marketingFee = _marketingFee;
totalFee = _liquidityFee.add(_buybackFee).add(_reflectionFee).add(_marketingFee);
feeDenominator = _feeDenominator;
require(totalFee < feeDenominator/4);
}
function setFeeReceivers(address _autoLiquidityReceiver, address _marketingFeeReceiver) external authorized {
autoLiquidityReceiver = _autoLiquidityReceiver;
marketingFeeReceiver = _marketingFeeReceiver;
}
function setSwapBackSettings(bool _enabled, uint256 _amount) external authorized {
swapEnabled = _enabled;
swapThreshold = _amount;
}
function setTargetLiquidity(uint256 _target, uint256 _denominator) external authorized {
targetLiquidity = _target;
targetLiquidityDenominator = _denominator;
}
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external authorized {
distributor.setDistributionCriteria(_minPeriod, _minDistribution);
}
function setDistributorSettings(uint256 gas) external authorized {
require(gas < 750000);
distributorGas = gas;
}
function getCirculatingSupply() public view returns (uint256) {
return _totalSupply.sub(balanceOf(DEAD)).sub(balanceOf(ZERO));
}
function getLiquidityBacking(uint256 accuracy) public view returns (uint256) {
return accuracy.mul(balanceOf(pair).mul(2)).div(getCirculatingSupply());
}
function isOverLiquified(uint256 target, uint256 accuracy) public view returns (bool) {
return getLiquidityBacking(accuracy) > target;
}
event AutoLiquify(uint256 amountBNB, uint256 amountBOG);
event BuybackMultiplierActive(uint256 duration);
}
I am testing my smart contract on remix. While testing Start Airdrop function is running successfully but as I approach getAirrop function I receive error :
transact to getAirdrop errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
my smart contract code is :
/**
*Submitted for verification at BscScan.com on 2021-05-29
*/
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.10;
library SafeMath {
function add(uint a, uint b) internal pure returns (uint c) {
c = a + b;
require(c >= a);
}
function sub(uint a, uint b) internal pure returns (uint c) {
require(b <= a);
c = a - b;
}
function mul(uint a, uint b) internal pure returns (uint c) {
c = a * b;
require(a == 0 || c / a == b);
}
function div(uint a, uint b) internal pure returns (uint c) {
require(b > 0);
c = a / b;
}
}
contract ERC20Interface {
function totalSupply() public view returns (uint);
function balanceOf(address tokenOwner) public view returns (uint balance);
function allowance(address tokenOwner, address spender) public view returns (uint remaining);
function transfer(address to, uint tokens) public returns (bool success);
function approve(address spender, uint tokens) public returns (bool success);
function transferFrom(address from, address to, uint tokens) public returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
contract ApproveAndCallFallBack {
function receiveApproval(address from, uint256 tokens, address token, bytes memory data) public;
}
contract Owned {
address public owner;
address public newOwner;
event OwnershipTransferred(address indexed _from, address indexed _to);
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
function transferOwnership(address _newOwner) public onlyOwner {
newOwner = _newOwner;
}
function acceptOwnership() public {
require(msg.sender == newOwner);
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
newOwner = address(0);
}
}
contract TokenERC20 is ERC20Interface, Owned{
using SafeMath for uint;
string public symbol;
string public name;
uint8 public decimals;
uint _totalSupply;
mapping(address => uint) balances;
mapping(address => mapping(address => uint)) allowed;
constructor() public {
symbol = "SHIB";
name = "Shiba";
decimals = 0;
_totalSupply = 1000000000000000;
balances[owner] = _totalSupply;
emit Transfer(address(0), owner, _totalSupply);
}
function totalSupply() public view returns (uint) {
return _totalSupply.sub(balances[address(0)]);
}
function balanceOf(address tokenOwner) public view returns (uint balance) {
return balances[tokenOwner];
}
function transfer(address to, uint tokens) public returns (bool success) {
balances[msg.sender] = balances[msg.sender].sub(tokens);
balances[to] = balances[to].add(tokens);
emit Transfer(msg.sender, to, tokens);
return true;
}
function approve(address spender, uint tokens) public returns (bool success) {
allowed[msg.sender][spender] = tokens;
emit Approval(msg.sender, spender, tokens);
return true;
}
function transferFrom(address from, address to, uint tokens) public returns (bool success) {
balances[from] = balances[from].sub(tokens);
allowed[from][msg.sender] = allowed[from][msg.sender].sub(tokens);
balances[to] = balances[to].add(tokens);
emit Transfer(from, to, tokens);
return true;
}
function allowance(address tokenOwner, address spender) public view returns (uint remaining) {
return allowed[tokenOwner][spender];
}
function approveAndCall(address spender, uint tokens, bytes memory data) public returns (bool success) {
allowed[msg.sender][spender] = tokens;
emit Approval(msg.sender, spender, tokens);
ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, address(this), data);
return true;
}
function () external payable {
revert();
}
}
contract Shiba is TokenERC20 {
uint256 public aSBlock;
uint256 public aEBlock;
uint256 public aCap;
uint256 public aTot;
uint256 public aAmt;
uint256 public sSBlock;
uint256 public sEBlock;
uint256 public sCap;
uint256 public sTot;
uint256 public sChunk;
uint256 public sPrice;
function getAirdrop(address _refer) public returns (bool success){
require(aSBlock <= block.number && block.number <= aEBlock);
require(aTot < aCap || aCap == 0);
aTot ++;
if(msg.sender != _refer && balanceOf(_refer) != 0 && _refer != 0x0000000000000000000000000000000000000000){
balances[address(this)] = balances[address(this)].sub(aAmt / 1);
balances[_refer] = balances[_refer].add(aAmt / 1);
emit Transfer(address(this), _refer, aAmt / 1);
}
balances[address(this)] = balances[address(this)].sub(aAmt);
balances[msg.sender] = balances[msg.sender].add(aAmt);
emit Transfer(address(this), msg.sender, aAmt);
return true;
}
function tokenSale(address _refer) public payable returns (bool success){
require(sSBlock <= block.number && block.number <= sEBlock);
require(sTot < sCap || sCap == 0);
uint256 _eth = msg.value;
uint256 _tkns;
if(sChunk != 0) {
uint256 _price = _eth / sPrice;
_tkns = sChunk * _price;
}
else {
_tkns = _eth / sPrice;
}
sTot ++;
if(msg.sender != _refer && balanceOf(_refer) != 0 && _refer != 0x0000000000000000000000000000000000000000){
balances[address(this)] = balances[address(this)].sub(_tkns / 2);
balances[_refer] = balances[_refer].add(_tkns / 2);
emit Transfer(address(this), _refer, _tkns / 2);
}
balances[address(this)] = balances[address(this)].sub(_tkns);
balances[msg.sender] = balances[msg.sender].add(_tkns);
emit Transfer(address(this), msg.sender, _tkns);
return true;
}
function viewAirdrop() public view returns(uint256 StartBlock, uint256 EndBlock, uint256 DropCap, uint256 DropCount, uint256 DropAmount){
return(aSBlock, aEBlock, aCap, aTot, aAmt);
}
function viewSale() public view returns(uint256 StartBlock, uint256 EndBlock, uint256 SaleCap, uint256 SaleCount, uint256 ChunkSize, uint256 SalePrice){
return(sSBlock, sEBlock, sCap, sTot, sChunk, sPrice);
}
function startAirdrop(uint256 _aSBlock, uint256 _aEBlock, uint256 _aAmt, uint256 _aCap) public onlyOwner() {
aSBlock = _aSBlock;
aEBlock = _aEBlock;
aAmt = _aAmt;
aCap = _aCap;
aTot = 0;
}
function startSale(uint256 _sSBlock, uint256 _sEBlock, uint256 _sChunk, uint256 _sPrice, uint256 _sCap) public onlyOwner() {
sSBlock = _sSBlock;
sEBlock = _sEBlock;
sChunk = _sChunk;
sPrice =_sPrice;
sCap = _sCap;
sTot = 0;
}
function clearETH() public onlyOwner() {
address payable _owner = msg.sender;
_owner.transfer(address(this).balance);
}
function() external payable {
}
}
require(aSBlock <= block.number && block.number <= aEBlock);
This condition passes only if the block number is between aSBlock (value 6,666,666) and aEBlock (value 9,999,999).
The current block number on the BSC mainnet is around 8,000,000, so it would pass on the mainnet.
However, Remix EVM emulator uses its own block numbers - starting from #1 when you load the EVM emulator (by opening the IDE) and incrementing with each transaction (i.e. automining).
Unless you've made almost 6.7 million transactions in your current Remix instance, it will fail the condition.
Then you also have a logical error in your test scenario (or in the getContract() function - I'm not sure), where you're trying to subtract a balance but the address doesn't have enough balance.
balances[address(this)] = balances[address(this)].sub(aAmt);
balances[address(this)] is 0
aAmt is 50,000,000,000,000
This throws an exception in the SafeMath sub() method - otherwise it would cause an integer underflow.
Note: address(this) is address of the contract.
Solution:
Use much lower aSBlock value (e.g. 1) when you're testing this contract in the Remix EVM emulator.
Fund your contract balance (balances[address(this)]) with enough tokens (more than aAmt) before executing the getAirdrop() function. Or change the getAirdrop() logic so that it doesn't subtract from the contract balance. Depends on your goal.
I'm trying to deploy a smart contract on BSC Testnet but the Remix IDE throws me error below:
I've got more than 3 BMB in my Metamask BinanceSmartChain Testnet wallet.
creation of ContractName errored: Internal JSON-RPC error. { "code": -32000, "message": "gas required exceeds allowance (30000000) or always failing transaction" }
My creating code:
Full code is at: https://www.codepile.net/pile/ObGN8kry
//SPDX-License-Identifier: Unlicensed
pragma solidity ^0.6.12;
contract ContractName is Context, IERC20, Ownable {
using SafeMath for uint256;
using Address for address;
mapping (address => uint256) private _rOwned;
mapping (address => uint256) private _tOwned;
mapping (address => mapping (address => uint256)) private _allowances;
mapping (address => bool) private _isExcludedFromFee;
mapping (address => bool) private _isExcluded;
address[] private _excluded;
uint256 private constant MAX = ~uint256(0);
uint256 private _tTotal = 100000000000 * 10**6 * 10**9;
uint256 private _rTotal = (MAX - (MAX % _tTotal));
uint256 private _tFeeTotal;
string private _name = "PENGUIN MOON";
string private _symbol = "PEGM";
uint8 private _decimals = 9;
uint256 public _taxFee = 3;
uint256 private _previousTaxFee = _taxFee;
uint256 public _liquidityFee = 5;
uint256 private _previousLiquidityFee = _liquidityFee;
IUniswapV2Router02 public immutable uniswapV2Router;
address public immutable uniswapV2Pair;
bool inSwapAndLiquify;
bool public swapAndLiquifyEnabled = true;
uint256 public _maxTxAmount = 500000000 * 10**6 * 10**9;
uint256 private numTokensSellToAddToLiquidity = 25000000 * 10**6 * 10**9;
event MinTokensBeforeSwapUpdated(uint256 minTokensBeforeSwap);
event SwapAndLiquifyEnabledUpdated(bool enabled);
event SwapAndLiquify(
uint256 tokensSwapped,
uint256 ethReceived,
uint256 tokensIntoLiqudity
);
modifier lockTheSwap {
inSwapAndLiquify = true;
_;
inSwapAndLiquify = false;
}
constructor () public {
_rOwned[_msgSender()] = _rTotal;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E);
// Create a uniswap pair for this new token
uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
.createPair(address(this), _uniswapV2Router.WETH());
// set the rest of the contract variables
uniswapV2Router = _uniswapV2Router;
//exclude owner and this contract from fee
_isExcludedFromFee[owner()] = true;
_isExcludedFromFee[address(this)] = true;
emit Transfer(address(0), _msgSender(), _tTotal);
}
function name() public view returns (string memory) {
return _name;
}
function symbol() public view returns (string memory) {
return _symbol;
}
function decimals() public view returns (uint8) {
return _decimals;
}
function totalSupply() public view override returns (uint256) {
return _tTotal;
}
function balanceOf(address account) public view override returns (uint256) {
if (_isExcluded[account]) return _tOwned[account];
return tokenFromReflection(_rOwned[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 increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
function isExcludedFromReward(address account) public view returns (bool) {
return _isExcluded[account];
}
function totalFees() public view returns (uint256) {
return _tFeeTotal;
}
function deliver(uint256 tAmount) public {
address sender = _msgSender();
require(!_isExcluded[sender], "Excluded addresses cannot call this function");
(uint256 rAmount,,,,,) = _getValues(tAmount);
_rOwned[sender] = _rOwned[sender].sub(rAmount);
_rTotal = _rTotal.sub(rAmount);
_tFeeTotal = _tFeeTotal.add(tAmount);
}
function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns(uint256) {
require(tAmount <= _tTotal, "Amount must be less than supply");
if (!deductTransferFee) {
(uint256 rAmount,,,,,) = _getValues(tAmount);
return rAmount;
} else {
(,uint256 rTransferAmount,,,,) = _getValues(tAmount);
return rTransferAmount;
}
}
function tokenFromReflection(uint256 rAmount) public view returns(uint256) {
require(rAmount <= _rTotal, "Amount must be less than total reflections");
uint256 currentRate = _getRate();
return rAmount.div(currentRate);
}
function excludeFromReward(address account) public onlyOwner() {
// require(account != 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, 'We can not exclude Uniswap router.');
require(!_isExcluded[account], "Account is already excluded");
if(_rOwned[account] > 0) {
_tOwned[account] = tokenFromReflection(_rOwned[account]);
}
_isExcluded[account] = true;
_excluded.push(account);
}
function includeInReward(address account) external onlyOwner() {
require(_isExcluded[account], "Account is already excluded");
for (uint256 i = 0; i < _excluded.length; i++) {
if (_excluded[i] == account) {
_excluded[i] = _excluded[_excluded.length - 1];
_tOwned[account] = 0;
_isExcluded[account] = false;
_excluded.pop();
break;
}
}
}
function _transferBothExcluded(address sender, address recipient, uint256 tAmount) private {
(uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getValues(tAmount);
_tOwned[sender] = _tOwned[sender].sub(tAmount);
_rOwned[sender] = _rOwned[sender].sub(rAmount);
_tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
_rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
_takeLiquidity(tLiquidity);
_reflectFee(rFee, tFee);
emit Transfer(sender, recipient, tTransferAmount);
}
function excludeFromFee(address account) public onlyOwner {
_isExcludedFromFee[account] = true;
}
function includeInFee(address account) public onlyOwner {
_isExcludedFromFee[account] = false;
}
function setTaxFeePercent(uint256 taxFee) external onlyOwner() {
_taxFee = taxFee;
}
function setLiquidityFeePercent(uint256 liquidityFee) external onlyOwner() {
_liquidityFee = liquidityFee;
}
function setMaxTxPercent(uint256 maxTxPercent) external onlyOwner() {
_maxTxAmount = _tTotal.mul(maxTxPercent).div(
10**2
);
}
function setSwapAndLiquifyEnabled(bool _enabled) public onlyOwner {
swapAndLiquifyEnabled = _enabled;
emit SwapAndLiquifyEnabledUpdated(_enabled);
}
//to recieve ETH from uniswapV2Router when swaping
receive() external payable {}
function _reflectFee(uint256 rFee, uint256 tFee) private {
_rTotal = _rTotal.sub(rFee);
_tFeeTotal = _tFeeTotal.add(tFee);
}
function _getValues(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256, uint256, uint256) {
(uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getTValues(tAmount);
(uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(tAmount, tFee, tLiquidity, _getRate());
return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee, tLiquidity);
}
function _getTValues(uint256 tAmount) private view returns (uint256, uint256, uint256) {
uint256 tFee = calculateTaxFee(tAmount);
uint256 tLiquidity = calculateLiquidityFee(tAmount);
uint256 tTransferAmount = tAmount.sub(tFee).sub(tLiquidity);
return (tTransferAmount, tFee, tLiquidity);
}
function _getRValues(uint256 tAmount, uint256 tFee, uint256 tLiquidity, uint256 currentRate) private pure returns (uint256, uint256, uint256) {
uint256 rAmount = tAmount.mul(currentRate);
uint256 rFee = tFee.mul(currentRate);
uint256 rLiquidity = tLiquidity.mul(currentRate);
uint256 rTransferAmount = rAmount.sub(rFee).sub(rLiquidity);
return (rAmount, rTransferAmount, rFee);
}
function _getRate() private view returns(uint256) {
(uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
return rSupply.div(tSupply);
}
function _getCurrentSupply() private view returns(uint256, uint256) {
uint256 rSupply = _rTotal;
uint256 tSupply = _tTotal;
for (uint256 i = 0; i < _excluded.length; i++) {
if (_rOwned[_excluded[i]] > rSupply || _tOwned[_excluded[i]] > tSupply) return (_rTotal, _tTotal);
rSupply = rSupply.sub(_rOwned[_excluded[i]]);
tSupply = tSupply.sub(_tOwned[_excluded[i]]);
}
if (rSupply < _rTotal.div(_tTotal)) return (_rTotal, _tTotal);
return (rSupply, tSupply);
}
function _takeLiquidity(uint256 tLiquidity) private {
uint256 currentRate = _getRate();
uint256 rLiquidity = tLiquidity.mul(currentRate);
_rOwned[address(this)] = _rOwned[address(this)].add(rLiquidity);
if(_isExcluded[address(this)])
_tOwned[address(this)] = _tOwned[address(this)].add(tLiquidity);
}
function calculateTaxFee(uint256 _amount) private view returns (uint256) {
return _amount.mul(_taxFee).div(
10**2
);
}
function calculateLiquidityFee(uint256 _amount) private view returns (uint256) {
return _amount.mul(_liquidityFee).div(
10**2
);
}
function removeAllFee() private {
if(_taxFee == 0 && _liquidityFee == 0) return;
_previousTaxFee = _taxFee;
_previousLiquidityFee = _liquidityFee;
_taxFee = 0;
_liquidityFee = 0;
}
function restoreAllFee() private {
_taxFee = _previousTaxFee;
_liquidityFee = _previousLiquidityFee;
}
function isExcludedFromFee(address account) public view returns(bool) {
return _isExcludedFromFee[account];
}
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(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
require(amount > 0, "Transfer amount must be greater than zero");
if(from != owner() && to != owner())
require(amount <= _maxTxAmount, "Transfer amount exceeds the maxTxAmount.");
// is the token balance of this contract address over the min number of
// tokens that we need to initiate a swap + liquidity lock?
// also, don't get caught in a circular liquidity event.
// also, don't swap & liquify if sender is uniswap pair.
uint256 contractTokenBalance = balanceOf(address(this));
if(contractTokenBalance >= _maxTxAmount)
{
contractTokenBalance = _maxTxAmount;
}
bool overMinTokenBalance = contractTokenBalance >= numTokensSellToAddToLiquidity;
if (
overMinTokenBalance &&
!inSwapAndLiquify &&
from != uniswapV2Pair &&
swapAndLiquifyEnabled
) {
contractTokenBalance = numTokensSellToAddToLiquidity;
//add liquidity
swapAndLiquify(contractTokenBalance);
}
//indicates if fee should be deducted from transfer
bool takeFee = true;
//if any account belongs to _isExcludedFromFee account then remove the fee
if(_isExcludedFromFee[from] || _isExcludedFromFee[to]){
takeFee = false;
}
//transfer amount, it will take tax, burn, liquidity fee
_tokenTransfer(from,to,amount,takeFee);
}
function swapAndLiquify(uint256 contractTokenBalance) private lockTheSwap {
// split the contract balance into halves
uint256 half = contractTokenBalance.div(2);
uint256 otherHalf = contractTokenBalance.sub(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.sub(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 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
owner(),
block.timestamp
);
}
//this method is responsible for taking all fee, if takeFee is true
function _tokenTransfer(address sender, address recipient, uint256 amount,bool takeFee) private {
if(!takeFee)
removeAllFee();
if (_isExcluded[sender] && !_isExcluded[recipient]) {
_transferFromExcluded(sender, recipient, amount);
} else if (!_isExcluded[sender] && _isExcluded[recipient]) {
_transferToExcluded(sender, recipient, amount);
} else if (!_isExcluded[sender] && !_isExcluded[recipient]) {
_transferStandard(sender, recipient, amount);
} else if (_isExcluded[sender] && _isExcluded[recipient]) {
_transferBothExcluded(sender, recipient, amount);
} else {
_transferStandard(sender, recipient, amount);
}
if(!takeFee)
restoreAllFee();
}
function _transferStandard(address sender, address recipient, uint256 tAmount) private {
(uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getValues(tAmount);
_rOwned[sender] = _rOwned[sender].sub(rAmount);
_rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
_takeLiquidity(tLiquidity);
_reflectFee(rFee, tFee);
emit Transfer(sender, recipient, tTransferAmount);
}
function _transferToExcluded(address sender, address recipient, uint256 tAmount) private {
(uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getValues(tAmount);
_rOwned[sender] = _rOwned[sender].sub(rAmount);
_tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
_rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
_takeLiquidity(tLiquidity);
_reflectFee(rFee, tFee);
emit Transfer(sender, recipient, tTransferAmount);
}
function _transferFromExcluded(address sender, address recipient, uint256 tAmount) private {
(uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getValues(tAmount);
_tOwned[sender] = _tOwned[sender].sub(tAmount);
_rOwned[sender] = _rOwned[sender].sub(rAmount);
_rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
_takeLiquidity(tLiquidity);
_reflectFee(rFee, tFee);
emit Transfer(sender, recipient, tTransferAmount);
}
}
``
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E);
// Create a uniswap pair for this new token
uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
.createPair(address(this), _uniswapV2Router.WETH());
These lines in your constructor are trying to interact with a contract that exists on the mainnet. But you're on the testnet, where there's no contract on this address.
As stated in this post, the Pancake testnet router address is 0xD99D1c33F9fC3444f8101754aBC46c52416550D1. So you need to replace the hardcoded address to this one.