I am trying to create a ICO contract (Crowdsale) which will fecilitate the sale of ERC20Token. While migrating the contract, I am getting stuck at an error
"SAMTokenSale" hit a require or revert statement with the following reason given:
- not enough tokens for transfer
In the constructor of TokenSale contract, I am initializing few things and also transferring some pre-defined amount of tokens to the Smart Contract. That's where, it's failing. But the admin of the contract has the initial total supply with it. So that should not fail, kinds stuck in this issue. Here are the code
- ERC20Token.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ERC20Interface {
function totalSupply() external view returns (uint);
function balanceOf(address account) external view returns (uint);
function transfer(address recipient, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint amount) external returns (bool);
function transferFrom(address sender,address recipient,uint amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
contract SAMToken is ERC20Interface {
string public name;
string public symbol;
uint8 public decimals;
uint public totalSupply;
address public admin;
mapping(address => uint) public balances;
mapping(address => mapping(address=>uint)) public allowances;
constructor(){
name = 'SAM Token';
symbol = "SAM";
decimals = 18;
totalSupply = 1000000 * 10 ** 18; // 1 million Tokens
admin = msg.sender;
balances[msg.sender] = totalSupply;
}
function transfer(address recipient, uint amount) external override returns(bool) {
require(balances[msg.sender] >= amount, 'not enough tokens for transfer');
balances[msg.sender] -= amount;
balances[recipient] += amount;
emit Transfer(msg.sender, recipient, amount);
return true;
}
function transferFrom(address sender, address recipient, uint amount) external override returns(bool) {
uint allowed = allowances[sender][msg.sender];
require(allowed >= amount && balances[sender] >=amount, 'allowance too low');
allowances[sender][msg.sender] -= amount;
balances[sender] -= amount;
balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
return true;
}
function approve(address spender, uint amount) external override returns(bool){
require(spender != msg.sender);
allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function burn(uint amount) external returns(bool){
require(balances[msg.sender] >= amount, 'not enought tokens to burn');
balances[msg.sender] -= amount;
totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
return true;
}
function allowance(address owner, address spender) external override view returns(uint){
return allowances[owner][spender];
}
function balanceOf(address account) external override view returns(uint){
return balances[account];
}
}
- TokenSaleContract
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {SAMToken} from './SAMToken.sol';
contract SAMTokenSale {
address admin;
SAMToken public tokenContract;
uint public tokenPrice;
uint public tokenSold;
uint tokensForSale = 100; // 100 tokens for sale
event Sell(address _address, uint _amount);
constructor(SAMToken _tokenContract, uint _tokenPrice){
admin = msg.sender;
tokenContract = _tokenContract;
tokenPrice = _tokenPrice;
tokenContract.transfer(address(this), tokensForSale); //sending tokens to the smart contract initially
}
function buyTokens(uint _tokenAmount) external payable {
require(msg.value == tokenPrice * _tokenAmount);
require(_tokenAmount <= tokenContract.balanceOf(address(this)),'not enough tokens left for sale');
require(tokenContract.transfer(msg.sender, _tokenAmount)); //immediate release, which should not be the case
tokenSold +=_tokenAmount;
emit Sell(msg.sender, _tokenAmount);
}
function endSale() external onlyAdmin() {
// transfer all the un-sold tokens back to admin
tokenContract.transfer(admin, tokenContract.balanceOf(address(this)));
//destroy the sale contract and transfer all ether balance to admin
selfdestruct(payable(admin));
}
modifier onlyAdmin(){
require(msg.sender == admin, 'only admin can do this');
_;
}
}
Kind of lost why this error on transfer function as the admin has the required amount of tokens. Any help will be much appreciated.
Thanks, Sam