Diagnosis 'web3.exceptions.ContractLogicError: execution reverted' error in a modified contract - solidity

Contract #1 is a functioning contract (runs with no issues)
Contract #2 is a modified version of Contract #1 with the following changes:
Modified exchangeRouterAddress from being hardcoded to being passed as an arg to the main function buy().
Brokedown buy() function into smaller functions due to "Stack Too Deep" compiling errors.
Hardcoded the value input from Contract #1
Now I've successfully compiled and deployed Contract #2 but running into error web3.exceptions.ContractLogicError: execution reverted. Please help me spot the cause of this error so that Contract #2 can perform just as Contract #1 without issues. Thanks
Contract #1:
pragma solidity ^0.8.12;
// SPDX-License-Identifier: UNLICENSED
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
}
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
}
interface IUniswapV2Router02 is IUniswapV2Router01 {
function swapExactETHForTokensSupportingFeeOnTransferTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable;
function swapExactTokensForTokensSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external;
}
interface IWETH {
function deposit() external payable;
}
contract ReBuy {
receive() external payable {}
address exchangeRouterAddress = 0x10ED43C718714eb63d5aA57B78B54704E256024E;
function buy(address baseToken, address token) public payable returns (uint256, uint256, uint256, uint256, uint256, uint256) {
uint256[] memory gas = new uint256[](2);
IUniswapV2Router02 exchangeRouter = IUniswapV2Router02(exchangeRouterAddress);
IERC20 _token = IERC20(token);
IERC20 _baseToken = IERC20(baseToken);
address[] memory path = new address[](2);
if(baseToken != exchangeRouter.WETH()) {
path[0] = exchangeRouter.WETH();
path[1] = baseToken;
exchangeRouter.swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(0, path, address(this), block.timestamp + 20);
}
else {
IWETH(baseToken).deposit{value: msg.value}();
}
uint256 amount = _baseToken.balanceOf(address(this));
path = new address[](2);
path[0] = baseToken;
path[1] = token;
uint256 expectedToken = exchangeRouter.getAmountsOut(amount, path)[1];
_baseToken.approve(exchangeRouterAddress, type(uint256).max);
uint256 startGas = gasleft();
exchangeRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(amount, 0, path, address(this), block.timestamp + 20);
gas[0] = startGas - gasleft();
uint256 receivedToken = _token.balanceOf(address(this));
path = new address[](2);
path[0] = token;
path[1] = baseToken;
uint256 expectedBaseToken = exchangeRouter.getAmountsOut(receivedToken, path)[1];
_token.approve(exchangeRouterAddress, type(uint256).max);
startGas = gasleft();
exchangeRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(receivedToken, 0, path, address(this), block.timestamp + 20);
gas[1] = startGas - gasleft();
uint256 receivedBaseToken = _baseToken.balanceOf(address(this));
return (expectedToken, receivedToken, gas[0], expectedBaseToken, receivedBaseToken, gas[1]);
}
}
Contract #2:
pragma solidity ^0.8.12;
// SPDX-License-Identifier: UNLICENSED
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
}
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
}
interface IUniswapV2Router02 is IUniswapV2Router01 {
function swapExactETHForTokensSupportingFeeOnTransferTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable;
function swapExactTokensForTokensSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external;
}
interface IWETH {
function deposit() external payable;
}
contract ReBuy {
struct ExchangeResult {
uint256 expected;
uint256 received;
uint256 gas;
}
function deposit(address token, address exchangeRouterAddress) internal {
IUniswapV2Router02 exchangeRouter = IUniswapV2Router02(exchangeRouterAddress);
address[] memory path = new address[](2);
if (token != exchangeRouter.WETH()) {
path[0] = exchangeRouter.WETH();
path[1] = token;
exchangeRouter.swapExactETHForTokensSupportingFeeOnTransferTokens{value: 1000000000000000000}(0, path, address(this), block.timestamp + 20);
}
else {
IWETH(token).deposit{value: 1000000000000000000}();
}
}
function exchangeToken(address fromToken, address toToken, address exchangeRouterAddress, uint256 amount) private returns (uint256, uint256, uint256)
{
IUniswapV2Router02 exchangeRouter = IUniswapV2Router02(exchangeRouterAddress);
uint256 expected;
uint256 received;
uint256 gas;
//uint256[] memory gas = new uint256[](2);
address[] memory path = new address[](2);
IERC20 token = IERC20(fromToken);
path[0] = fromToken;
path[1] = toToken;
expected = exchangeRouter.getAmountsOut(amount, path)[1];
token.approve(exchangeRouterAddress, type(uint256).max);
gas = gasleft();
exchangeRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(amount, 0, path, address(this), block.timestamp + 20);
gas = gas - gasleft();
token = IERC20(toToken);
received = token.balanceOf(address(this));
return (expected, received, gas);
}
function buy(address baseToken, address token, address exchangeRouterAddress) public payable returns (uint256, uint256, uint256, uint256, uint256, uint256)
{
IERC20 _baseToken = IERC20(baseToken);
uint256 amount;
ExchangeResult memory tokenRes;
ExchangeResult memory baseTokenRes;
deposit(baseToken, exchangeRouterAddress);
amount = _baseToken.balanceOf(address(this));
(tokenRes.expected, tokenRes.received, tokenRes.gas) = exchangeToken(baseToken, token, exchangeRouterAddress, amount);
(baseTokenRes.expected, baseTokenRes.received, baseTokenRes.gas) = exchangeToken(token, baseToken, exchangeRouterAddress, tokenRes.received);
// Finally return all results
return (tokenRes.expected, tokenRes.received, tokenRes.gas, baseTokenRes.expected, baseTokenRes.received, baseTokenRes.gas);
}
}
Sample of how I call the buy() function (Contract #2 entry function) in python:
token = '0x67382a3364b97e09f727afb388fe817de18f7a18' # Random token just for test
base_token = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c' # WBNB
router_address = '0x10ED43C718714eb63d5aA57B78B54704E256024E' # Pancake Router
deployed_contract = # Place Contract #2 address after deployment here
deployed_contract_ABI = '[{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"baseToken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"exchangeRouterAddress","type":"address"}],"name":"simulate_txn","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]'
deployed_contract = web3.toChecksumAddress(deployed_contract )
contract = web3.eth.contract(address=deployed_contract , abi=deployed_contract_ABI )
results = contract.functions.buy(base_token , token, router_address ).call()
print(results) # Returns 6 values

Related

Error during calling function in smart contract

I need some understanding why I get errors in the following code. I try to call function getAmountOutMin to get the amount of particular token(_tokenOut) I can buy (amountOutMins) on _amountIn of token _tokenIn. But regardless of amount I specify in _amountIn(for instance, I specify 10000000000000000 WEI, that's about 0.01 WETH) I get the error.
call to Uniswap.getAmountOutMin errored: execution reverted
As I token_in I specify 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6 address(WETH in Goerli), token_out = 0x78c26A88c19ae0311e0121f7350735b842AFFd41.
I do need some help to understand what I'm doing wrong
pragma solidity ^0.8.7;
import "#openzeppelin/contracts/token/ERC20/IERC20.sol";
import "hardhat/console.sol";
interface IUniswapV2Router {
function getAmountsOut(uint256 amountIn, address[] memory path)
external
view
returns (uint256[] memory amounts);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
uint256 deadline
) external returns (uint256[] memory amounts);
}
contract Uniswap {
address private constant uniswap_goerli = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
address private constant WETH_Goerli = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6;
address private constant ETH_Goerli = 0x8d27431c473E83611847D195d325972e80D1F4c1;
///call via web3
function approve_for_uniswap(uint _amount_to_send) public payable{
// IERC20(ETH_Goerli).approve(address(this),_amount_to_send);
// IERC20(ETH_Goerli).transfer(address(this),_amount_to_send);
IERC20(ETH_Goerli).approve(uniswap_goerli,_amount_to_send);
}
function _swap_token(address _token_in,address _token_out,uint _amountIn,uint _amountOutMin,address _to) external{
address[] memory path;
if (_token_in==WETH_Goerli || _token_out == WETH_Goerli){
path = new address[](2);
path[0]=_token_in;
path[1] = _token_out;}
else {
path = new address[](3);
path[0] = _token_in;
path[1] = WETH_Goerli;
path[2] = _token_out;
}
IUniswapV2Router(uniswap_goerli).swapExactTokensForTokens(_amountIn, _amountOutMin, path, _to, block.timestamp);
}
function getAmountOutMin(address _tokenIn, address _tokenOut, uint256 _amountIn) external view returns (uint256) {
address[] memory path;
if (_tokenIn == WETH_Goerli || _tokenOut == WETH_Goerli) {
path = new address[](2);
path[0] = _tokenIn;
path[1] = _tokenOut;
} else {
path = new address[](3);
path[0] = _tokenIn;
path[1] = WETH_Goerli;
path[2] = _tokenOut;
}
uint256[] memory amountOutMins = IUniswapV2Router(uniswap_goerli).getAmountsOut(_amountIn, path);
return amountOutMins[path.length -1];}```

Solidty smart contract blacklist function

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~

Solidity issues with transferFrom()

I'm only about a week into Solidity so please don't go easy on me. I'm writing a new token contract and am having issues using the transferFrom() function. I can do normal transfers and approve another address to spend funds but am unable to transfer from someone else's wallet (while approved).
Any help is appreciated!
Code:
//SPDX-License-Identifier: MIT
pragma solidity >=0.8.12 <0.9.0;
interface IERC20 {
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, 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 from, address to, 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 IUniswapV2Router01 {
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);
}
interface IUniswapV2Router02 is IUniswapV2Router01 {
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
interface IUniswapV2Factory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
contract TestContract is IERC20 {
uint256 public constant BUYFEE = 42069;//4.2069
uint256 public constant SELLFEE = 8008135;//8.008135
address public COMMUNITYWALLET = 0x761Eb6556c69B6484e2FDbd76C527cC4e3628Ae0;
uint8 public CTAX = 50;
uint8 public LTAX = 50;
uint8 public TTAX = 100;
uint256 public THRESHOLD;
string private _name = "Test";
string private _symbol = "TEST";
uint8 private _decimals = 18;
uint256 private _totalSupply= 1000000000 * 10 ** 18;
mapping(address => uint256) private _balance;
mapping(address => mapping(address => uint256)) private _allowance;
mapping(address => bool) private _isRouter;
mapping(address => bool) private _isExcluded;
address private _ownerAddress;
address private _dead = 0x000000000000000000000000000000000000dEaD;
IUniswapV2Router02 private uniswapV2Router;
address private uniswapV2Pair;
event SetTaxes(uint256 communityTax, uint256 liquidityTax);
event SetCommunityWallet(address communityWallet);
event ClearStuckEth(address communityWallet, uint256 ethCleared);
event ClearStuckTokens(address recipient, uint256 contractTokenBalance);
event Liquidate(uint256 ethForCommunity, uint256 ethForLiquidity, uint256 tokensForLiquidity);
event UpdateTokenThreshold(uint256 tokenThreshold);
event TransferOwnership(address oldOwner, address ownerAddress);
event AddToExcluded(address pAddress);
event RemoveFromExcluded(address pAddress);
constructor(uint8 pThresholdPercent) {
_ownerAddress = msg.sender;
_update(msg.sender, _totalSupply);
uniswapV2Router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this), uniswapV2Router.WETH());
_isRouter[0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D] = true;
_isExcluded[_ownerAddress] = true;
_updateTokenThreshold(pThresholdPercent);
}
receive() external payable {}
modifier protected() {
require(msg.sender == _ownerAddress);
_;
}
function transfer(address pTo, uint256 pToken) external returns (bool) {
_transfer(msg.sender, pTo, pToken);
return true;
}
function approve(address pSpender, uint256 pToken) external returns (bool) {
_approve(msg.sender, pSpender, pToken);
return true;
}
function transferFrom(address pSpender, address pRecipient, uint256 pToken) external returns (bool) {
_transfer(pSpender, pRecipient, pToken);
_approve(pSpender, msg.sender, _allowance[pSpender][msg.sender] - pToken);
return true;
}
function totalSupply() external view returns (uint256) {return _totalSupply;}
function decimals() external view returns (uint8) {return _decimals;}
function symbol() external view returns (string memory) {return _symbol;}
function name() external view returns (string memory) {return _name;}
function getOwner() external view returns (address) { return _ownerAddress; }
function balanceOf(address pAddress) external view returns (uint256) {return _balance[pAddress];}
function allowance(address pOwner, address pSpender) external view returns (uint256) {return _allowance[pOwner][pSpender];}
function _transfer(address pFrom, address pTo, uint256 pToken) private {
require(pFrom != address(0));
require(pTo != address(0));
require(pToken > 0);
require(pToken <= _balance[pFrom]);
uint256 fee = 0;
if(_balance[address(this)] >= THRESHOLD) { _liquidate(); }
if(!_isExcluded[pFrom] && !_isExcluded[pTo]) {
if(_isRouter[pFrom]) {
fee = _calculateBuyTax(pToken);//Tax on buys
_balance[address(this)] += fee;
}
else if(_isRouter[pTo]) {
fee = _calculateSellTax(pToken);//Tax on sells
_balance[address(this)] += fee;
}
}
_balance[msg.sender] -= pToken;
_balance[pTo] += (pToken - fee);
emit Transfer(msg.sender, pTo, pToken);
}
function _approve(address pOwner, address pSpender, uint256 pToken) private {
require(pOwner != address(0));
require(pSpender != address(0));
_allowance[pOwner][pSpender] = pToken;
emit Approval(pOwner, pSpender, pToken);
}
function _update(address pRecipient, uint256 pToken) private {
require(pRecipient != address(0));
_balance[pRecipient] += pToken;
emit Transfer(address(0), pRecipient, pToken);
}
function _liquidate() private {
uint256 tokensForLiquidity = (THRESHOLD * LTAX / 100);
uint256 amountToSwap = THRESHOLD - tokensForLiquidity;
_swapTokensForEth(amountToSwap);
uint256 totalEthBalance = address(this).balance;
uint256 ethForCommunity = totalEthBalance * CTAX / 100;
uint256 ethForLiquidity = totalEthBalance - ethForCommunity;
if (totalEthBalance > 0) {
payable(COMMUNITYWALLET).call{value:ethForCommunity};
}
if (tokensForLiquidity > 0) {
_addLiquidity(tokensForLiquidity, ethForLiquidity);
_balance[_dead] += tokensForLiquidity;
}
_balance[address(this)] -= THRESHOLD;
emit Liquidate(ethForCommunity, ethForLiquidity, tokensForLiquidity);
}
function _swapTokensForEth(uint256 pToken) private {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
_approve(address(this), address(uniswapV2Router), pToken);
uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
pToken,
0,
path,
address(this),
block.timestamp + 15
);
}
function _addLiquidity(uint256 pToken, uint256 pEth) private returns (bool) {
_approve(address(this), address(uniswapV2Router), pToken);
uniswapV2Router.addLiquidityETH{value: pEth}(address(this), pToken, 0, 0, _dead, block.timestamp + 15);
return true;
}
function _calculateBuyTax(uint256 pToken) private pure returns (uint256) {
return (pToken * BUYFEE) / 10**6;
}
function _calculateSellTax(uint256 pToken) private pure returns (uint256) {
return (pToken * SELLFEE) / 10**8;
}
function _updateTokenThreshold(uint256 pThresholdPercent) private {
THRESHOLD = _totalSupply * pThresholdPercent / 100;
emit UpdateTokenThreshold(THRESHOLD);
}
function setTaxes(uint8 pCommunityTax, uint8 pLiquidityTax) external protected {
CTAX = pCommunityTax;
LTAX = pLiquidityTax;
TTAX = CTAX + LTAX;
require(TTAX >= 0 && TTAX <= 100);
emit SetTaxes(CTAX, LTAX);
}
function setCommunityWallet(address payable pCommunityWallet) external protected {
COMMUNITYWALLET = pCommunityWallet;
emit SetCommunityWallet(COMMUNITYWALLET);
}
function transferOwnership(address pOwner) external protected {
address oldOwner = _ownerAddress;
_ownerAddress = pOwner;
emit TransferOwnership(oldOwner, _ownerAddress);
}
function clearStuckEth() external protected {
uint256 contractETHBalance = address(this).balance;
if(contractETHBalance > 0){
payable(COMMUNITYWALLET).call{value:contractETHBalance};
}
emit ClearStuckEth(COMMUNITYWALLET, contractETHBalance);
}
function clearStuckTokens() external protected {
uint256 contractTokenBalance = _balance[address(this)];
if(contractTokenBalance > 0) {
_balance[COMMUNITYWALLET] += _balance[address(this)];
_balance[address(this)] = 0;
}
emit ClearStuckTokens(COMMUNITYWALLET, contractTokenBalance);
}
function manualLiquidate() external protected {
_liquidate();
}
function updateTokenThreshold(uint256 pThresholdPercent) external protected returns (bool) {
_updateTokenThreshold(pThresholdPercent);
return true;
}
function addToExcluded(address pAddress) external protected {
_isExcluded[pAddress] = true;
emit AddToExcluded(pAddress);
}
function removeFromExcluded(address pAddress) external protected {
_isExcluded[pAddress] = false;
emit RemoveFromExcluded(pAddress);
}
}
this was a small mistake and it is the correct code that is to be changed,
function transferFrom(address pSpender, address pRecipient, uint256 pToken) external returns (bool) {
_allowance[from][pSpender] = safeSub(_allowance[pSpender][msg.sender], pToken);
_transfer(pSpender, pRecipient, pToken);
return true;
}
function _approve(address pOwner, address pSpender, uint256 pToken) public returns (bool success) {
_allowance[pOwner][pSpender] = tokens;
emit Approval(pOwner, pSpender, tokens);
return true;
}
if this is still having issue, do share me the contract link.
I was able to transfer after switching browsers and it may have just been a caching issue. This contract has been updated since and works. Thanks.

Fulfilling Chainlink Job requests not successful

fulfilling request for ATestNetConsumer.sol failed. Every time I request for current ethereum price it always returns uint256: 0.
enter image description here
I followed the steps carefully but I don't know what I am missing - https://docs.chain.link/docs/fulfilling-requests/.
Please help, the codes and contract address are listed below:
Oracle Contract Address: "0xC3b625566d22aBd0C6Ce659105bE29054D03BFa4"
EVM Chainlink Address:
"0x711715E74FfDf0c22eC43607a03732Cefcfc60A7"
_jobId = "76eb4b9925014082bb58389e3ffd7f6a"
type = "directrequest"
schemaVersion = 1
name = "Get > Uint256"
externalJobID = "76eb4b99-2501-4082-bb58-389e3ffd7f6a"
maxTaskDuration = "0s"
contractAddress = "0xC3b625566d22aBd0C6Ce659105bE29054D03BFa4"
minIncomingConfirmations = 0
observationSource = """
decode_log [type="ethabidecodelog"
abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)"
data="$(jobRun.logData)"
topics="$(jobRun.logTopics)"]
decode_cbor [type="cborparse" data="$(decode_log.data)"]
fetch [type="http" method=GET url="$(decode_cbor.get)"]
parse [type="jsonparse" path="$(decode_cbor.path)" data="$(fetch)"]
multiply [type="multiply" input="$(parse)" times=100]
encode_data [type="ethabiencode" abi="(uint256 value)" data="{ \\"value\\": $(multiply) }"]
encode_tx [type="ethabiencode"
abi="fulfillOracleRequest(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes32 data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}"
]
submit_tx [type="ethtx" to="0xC3b625566d22aBd0C6Ce659105bE29054D03BFa4" data="$(encode_tx)"]
decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""
Here is for the contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "#chainlink/contracts/src/v0.8/ConfirmedOwner.sol";
contract ATestnetConsumer is ChainlinkClient, ConfirmedOwner {
using Chainlink for Chainlink.Request;
uint256 constant private ORACLE_PAYMENT = 1 * LINK_DIVISIBILITY;
uint256 public currentPrice;
int256 public changeDay;
bytes32 public lastMarket;
event RequestEthereumPriceFulfilled(
bytes32 indexed requestId,
uint256 indexed price
);
event RequestEthereumChangeFulfilled(
bytes32 indexed requestId,
int256 indexed change
);
event RequestEthereumLastMarket(
bytes32 indexed requestId,
bytes32 indexed market
);
constructor() ConfirmedOwner(msg.sender){
setPublicChainlinkToken();
}
function requestEthereumPrice(address _oracle, string memory _jobId)
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), address(this), this.fulfillEthereumPrice.selector);
req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");
req.add("path", "USD");
req.addInt("times", 100);
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function requestEthereumChange(address _oracle, string memory _jobId)
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), address(this), this.fulfillEthereumChange.selector);
req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");
// req.add("path", "RAW.ETH.USD.CHANGEPCTDAY"); // Chainlink nodes prior to 1.0.0 support this format
req.add("path", "RAW,ETH,USD,CHANGEPCTDAY"); // Chainlink nodes 1.0.0 and later support this format
req.addInt("times", 1000000000);
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function requestEthereumLastMarket(address _oracle, string memory _jobId)
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), address(this), this.fulfillEthereumLastMarket.selector);
req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");
string[] memory path = new string[](4);
path[0] = "RAW";
path[1] = "ETH";
path[2] = "USD";
path[3] = "LASTMARKET";
req.addStringArray("path", path);
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function fulfillEthereumPrice(bytes32 _requestId, uint256 _price)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestEthereumPriceFulfilled(_requestId, _price);
currentPrice = _price;
}
function fulfillEthereumChange(bytes32 _requestId, int256 _change)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestEthereumChangeFulfilled(_requestId, _change);
changeDay = _change;
}
function fulfillEthereumLastMarket(bytes32 _requestId, bytes32 _market)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestEthereumLastMarket(_requestId, _market);
lastMarket = _market;
}
function getChainlinkToken() public view returns (address) {
return chainlinkTokenAddress();
}
function withdrawLink() public onlyOwner {
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer");
}
function cancelRequest(
bytes32 _requestId,
uint256 _payment,
bytes4 _callbackFunctionId,
uint256 _expiration
)
public
onlyOwner
{
cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration);
}
function stringToBytes32(string memory source) private pure returns (bytes32 result) {
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly { // solhint-disable-line no-inline-assembly
result := mload(add(source, 32))
}
}
}
The contract address for ATestNetConsumer.sol is funded.

Remix error The transaction has been reverted to the initial state

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.