I have an IDOmaster con`enter code here`tract that I call a function to create an IDO, when I execute the IDOmaster contract it works perfectly, but when I call the function, the Remix always gives me the same error.
I use Remix and perform a web3 inject to deploy them.
First I deploy the Master contract and once deployed I call the CreateIDO function, I pass the parameters and this is when I always get this error.
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Internal JSON-RPC error. { "code": 3, "message": "execution reverted: Address: call to non-contract", "data": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001d416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000" }
I don't know how to continue
The function has 4 parameters that I have to pass in
Token name, token, symbol, tuple that I paste below and quantity
["0x9cE15ffdb115248137c6578C4f7C28083E8957Bd", "35000000000000000", "1632495600", "1635681600", "10000000000000000", "10000000000000000000", "50000000000000000000", "500000000000000000000"]
this is contract Master
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./IDOPool.sol";
import "./IDOStructures.sol";
contract IDOMaster is Ownable {
using SafeMath for uint256;
using SafeERC20 for ERC20;
mapping(uint256 => IDOPool) public idoPools;
mapping(address => bool) public isExistingPools;
uint256 public totalPools;
uint256 public feeAmount;
address payable public feeWallet;
event IDOCreated(address owner, address idoPool,
uint256 poolIndex,
string poolName,
string poolType,
PoolInfo poolInfo,
uint256 maxDistributedTokenAmount);
event FeeAmountUpdated(uint256 newFeeAmount);
event FeeWalletUpdated(address newFeeWallet);
constructor(
) {
totalPools = 1;
//feeAmount = 2 * 10 ** 18;
feeAmount = 10**17;
feeWallet = payable(0x9cE15ffdb115248137c6578C4f7C28083E8957Bd);
}
function setFeeAmount(uint256 _newFeeAmount) external onlyOwner {
feeAmount = _newFeeAmount;
emit FeeAmountUpdated(_newFeeAmount);
}
function setFeeWallet(address payable _newFeeWallet) external onlyOwner {
feeWallet = _newFeeWallet;
emit FeeWalletUpdated(_newFeeWallet);
}
function approve(ERC20 _rewardToken) external onlyOwner{
_rewardToken.safeApprove(address(this), 1000);
}
function increaseAllowance(ERC20 _rewardToken) external onlyOwner{
_rewardToken.safeIncreaseAllowance(address(this), 1000);
}
function createIDO(
string memory _poolName,
string memory _poolType,
PoolInfo memory _poolInfo,
uint256 _maxDistributedTokenAmount
// ERC20 _rewardToken
) payable external {
// require( msg.value > feeAmount, "User should pay over than the IDO pool creation fee.");
// uint256 ethAmount = address(this).balance;
// require(ethAmount < feeAmount, "User should pay over than");
// if(ethAmount > 10**17){
// feeWallet.transfer(ethAmount - 10**17);
// (bool trSuccess, ) = feeWallet.call{value: ethAmount - 10**17}("");
// require(trSuccess, "Transfer failed.");
// }
// _rewardToken.safeTransferFrom(
// msg.sender,
// address(this),
// 1000
// );
IDOPool idoPool =
new IDOPool(
totalPools,
_poolName,
_poolType,
_poolInfo
);
idoPool.transferOwnership(msg.sender);
if(isExistingPools[address(idoPool)] == false){
idoPools[totalPools] = idoPool;
totalPools = totalPools + 1;
}
isExistingPools[address(idoPool)] = true;
ERC20(_poolInfo.rewardToken).safeTransferFrom(
msg.sender,
address(idoPool),
_maxDistributedTokenAmount
);
emit IDOCreated(msg.sender,
address(idoPool),
totalPools - 1,
_poolName,
_poolType,
_poolInfo,
_maxDistributedTokenAmount);
}
receive() external payable {}
}
And this is contract Create IDO
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./IDOStructures.sol";
interface IPancakeSwapV2Factory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
interface IPancakeSwapV2Router02 {
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address calldata path,
address to,
uint256 deadline
) external;
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
}
contract IDOPool is Ownable, ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for ERC20;
uint256 public poolIndex;
string public poolName;
string public poolType;
IPancakeSwapV2Router02 private pancakeV2Router; // pancakeswap v2 router
address private pancakeV2Pair; // pancakeswap v2 pair
uint256 public tokensForDistribution;
uint256 public distributedTokens;
uint256 public liquidityETH;
uint256 public liquidityToken;
PoolInfo public poolInfo;
StatusInfo public status;
mapping(address => UserInfo) public userInfo;
bool public success;
bool public saleEnd;
bool public openRefund;
event TokensDebt(
address indexed holder,
uint256 ethAmount,
uint256 tokenAmount
);
event TokensWithdrawn(address indexed holder, uint256 amount);
constructor(
uint256 _poolIndex,
string memory _poolName,
string memory _poolType,
PoolInfo memory _poolInfo
) {
//poolIndex = 1;
//poolName = "NFTTUBE";
//poolType = "NFTTUBE";
poolIndex = _poolIndex;
poolName = _poolName;
poolType = _poolType;
poolInfo = _poolInfo;
require(
_poolInfo.startTimestamp > block.timestamp,
"Start timestamp must be more than current block"
);
require(
_poolInfo.startTimestamp < _poolInfo.finishTimestamp,
"Start timestamp must be less than finish timestamp"
);
require(
_poolInfo.softEthCap > 0,
"Soft capital must be more than 0"
);
require(
_poolInfo.softEthCap < _poolInfo.hardEthCap,
"Soft capital must be less than hard capital"
);
success = false;
saleEnd = false;
openRefund = false;
}
modifier checkPresale() {
if(block.timestamp > poolInfo.startTimestamp){
status.started = true;
}
uint256 ethAmount = address(this).balance;
if(ethAmount >= poolInfo.softEthCap){
success = true;
}
if( ethAmount >= poolInfo.hardEthCap){
status.filled = true;
}
if(block.timestamp >= poolInfo.finishTimestamp){
if(ethAmount < poolInfo.softEthCap){
openRefund = true;
}
status.started = false;
status.ended = true;
}
if(ethAmount > poolInfo.hardEthCap || block.timestamp >= poolInfo.finishTimestamp){
addLiquidity(liquidityETH, liquidityToken);
// pancakeswap addition,
saleEnd = true;
}
_;
}
function pay() payable external checkPresale {
require(block.timestamp >= poolInfo.startTimestamp, "Not started");
require(block.timestamp < poolInfo.finishTimestamp, "Ended");
require(msg.value >= poolInfo.minEthPayment, "Less then min amount");
require(msg.value <= poolInfo.maxEthPayment, "More then max amount");
require(openRefund == false, "Sale must not be refund mode");
require(saleEnd == false, "Sale must be open");
uint256 ethAmount = address(this).balance;
require(ethAmount <= poolInfo.hardEthCap, "HardCap Overfilled");
UserInfo storage user = userInfo[msg.sender];
require(user.totalInvestedETH.add(msg.value) <= poolInfo.maxEthPayment, "More then max amount");
uint256 tokenAmount = getTokenAmount(msg.value);
tokensForDistribution = tokensForDistribution.add(tokenAmount);
user.totalInvestedETH = user.totalInvestedETH.add(msg.value);
user.total = user.total.add(tokenAmount);
user.debt = user.debt.add(tokenAmount);
emit TokensDebt(msg.sender, msg.value, tokenAmount);
}
function getTokenAmount(uint256 ethAmount)
internal
view
returns (uint256)
{
uint256 decimals = ERC20(poolInfo.rewardToken).decimals();
return ethAmount.mul(10**decimals).div(poolInfo.tokenPrice);
}
/// @dev Allows to claim tokens for the specific user.
/// @param _user Token receiver.
function claimFor(address _user) external {
proccessClaim(_user);
}
/// @dev Allows to claim tokens for themselves.
function claim() external {
proccessClaim(msg.sender);
}
/// @dev Proccess the claim.
/// @param _receiver Token receiver.
function proccessClaim(
address _receiver
) internal nonReentrant{
require(success == true, "Sale must be successed");
require(saleEnd == true, "Sale must be finished");
UserInfo storage user = userInfo[_receiver];
uint256 _amount = user.debt;
if (_amount > 0) {
user.debt = 0;
distributedTokens = distributedTokens.add(_amount);
ERC20(poolInfo.rewardToken).safeTransfer(_receiver, _amount);
emit TokensWithdrawn(_receiver,_amount);
}
}
function refund(address _user) external {
processRefund(_user);
}
function processRefund(
address _receiver
) internal nonReentrant {
require(success == false, "Presale failed");
require(openRefund == true, "Pool need to open refund");
UserInfo storage user = userInfo[_receiver];
uint256 fee = user.totalInvestedETH.mul(8).div(100);
uint256 _amount = user.totalInvestedETH - fee;
(bool trSuccess, ) = msg.sender.call{value: _amount}("");
require(trSuccess, "Transfer failed.");
}
function withdrawETH(uint256 amount) external onlyOwner {
(bool trSuccess, ) = msg.sender.call{value: amount}("");
require(trSuccess, "Transfer failed.");
}
function withdrawNotSoldTokens(address _receiver) external onlyOwner {
require(block.timestamp > poolInfo.finishTimestamp, "Withdraw allowed after stop accept ETH");
uint256 balance = ERC20(poolInfo.rewardToken).balanceOf(address(this));
ERC20(poolInfo.rewardToken).safeTransfer(_receiver, balance.add(distributedTokens).sub(tokensForDistribution));
}
function cancelPool() external onlyOwner{
success = false;
saleEnd = true;
openRefund = true;
status.cancelled = true;
}
function getPoolInfo() public view returns(PoolInfo memory){
return poolInfo;
}
function addLiquidity(uint256 ethAmount, uint256 tokenAmount) internal {
pancakeV2Router = IPancakeSwapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E); // mainnet Router address
ERC20(poolInfo.rewardToken).approve(address(pancakeV2Router), tokenAmount);
pancakeV2Pair = IPancakeSwapV2Factory(pancakeV2Router.factory()).createPair(address(poolInfo.rewardToken), pancakeV2Router.WETH());
pancakeV2Router.addLiquidityETH{value: ethAmount}(address(poolInfo.rewardToken), tokenAmount, 0, 0, owner(), block.timestamp);
ERC20(pancakeV2Pair).approve(address(pancakeV2Router),type(uint256).max);
}
function setliquidityETH(uint256 _newETHAmount) external onlyOwner {
liquidityETH = _newETHAmount;
}
function setliquidtyToken(uint256 _newTokenAmount) external onlyOwner {
liquidityToken = _newTokenAmount;
}
function setVoting(bool isVote)external onlyOwner{
status.voting = isVote;
}
function setCertified(bool isCertified)external onlyOwner{
status.certified = isCertified;
}
function setPoolInfo(PoolInfo memory _poolInfo)external onlyOwner{
poolInfo = _poolInfo;
}
receive() external payable {}
}