0

I am building a smart contract that will be used to perform the ICO on my currency.

However, in the tests I'm doing, I'm having an error when transferring the tokens that are in my contract to the person who is buying.

The error is being:

 ERC20: transfer amount exceeds balance -- Reason given: ERC20: transfer amount exceeds balance.

My smart contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract SALES is Ownable {
  using SafeMath for uint256;
  
  IERC20 token;

  uint256 private RATE = 3000; // Number of tokens per Ether
  uint256 private CAP = 5350; // Cap in Ether
  uint256 private START = 1636914760; // Mar 26, 2018 @ 12:00 EST
  uint256 private DAYS = 45; // 45 Day
  
  uint256 public initialTokens; // Initial number of tokens available
  bool public initialized = false;
  uint256 public raisedAmount = 0;

  /**
   * BoughtTokens
   * @dev Log tokens bought onto the blockchain
   */
  event BoughtTokens(address indexed to, uint256 value);

  constructor(address _token){
    setAddrERC20(_token);
  }
   /**
   * buyTokens
   * @dev function that sells available tokens
   **/
  function buyTokens() public payable whenSaleIsActive {
    uint256 weiAmount = msg.value; // Calculate tokens to sell
    uint256 tokens = weiAmount.mul(RATE);    

    emit BoughtTokens(msg.sender, tokens); // log event onto the blockchain
    raisedAmount = raisedAmount.add(msg.value); // Increment raised amount
    token.transfer(msg.sender, tokens); // Send tokens to buyer
    
    payable(owner()).transfer(msg.value);// Send money to owner
  }

  /**
   * whenSaleIsActive
   * @dev ensures that the contract is still active
   **/
  modifier whenSaleIsActive() {
    // Check if sale is active
    assert(isActive());
    _;
  }

  function isActive() public view returns (bool) {
    return (
        //initialized == true &&
        block.timestamp >= START && // Must be after the START date
        block.timestamp <= START.add(DAYS * 1 days) && // Must be before the end date
        goalReached() == false // Goal must not already be reached
    );
  }

  /**
   * goalReached
   * @dev Function to determin is goal has been reached
   **/
  function goalReached() public view returns (bool) {
    return (raisedAmount >= CAP * 1 ether);
  }

  function setRate(uint _rate) public onlyOwner{
    RATE = _rate;
  }

  function setCap(uint _cap) public onlyOwner{
    CAP = _cap;
  }

  function setStart(uint _start) public onlyOwner{
    START = _start;
  }

  function setDays(uint _days) public onlyOwner{
    DAYS = _days;
  }

  function setAddrERC20(address _tokenAddr) public onlyOwner{
    require(_tokenAddr != address(0));
    token = IERC20(_tokenAddr);
  }
}

My file test.js

const { expect } = require('chai');

const SALES = artifacts.require('SALES');
const TOKEN = artifacts.require('TOKEN');

contract("SALES", ([accountPrivateSales, investor1, investor2]) => {

    // const accountPrivateSales = "";
    const amountPrivateSales = "10000000";
    let coinInstance, contractInstance;

    before(async () => {       
        coinInstance = await TOKEN.new();
        contractInstance = await SALES.new(coinInstance.address);        
    });

    describe("Validate pre-sales from account privateSales", async () => {
        it(`Verifiy amount in accountPrivateSales to be equal ${amountPrivateSales}`, async () => {
            let total  = await coinInstance.balanceOf(accountPrivateSales);
           
            expect(web3.utils.fromWei(total)).to.be.equal(amountPrivateSales);
        });
        it(`Verifiy amount in smart contract SALES to be equal 0`, async () => {
            let total  = await coinInstance.balanceOf(contractInstance.address);
           
            expect(web3.utils.fromWei(total)).to.be.equal("0");
        });
        it(`Transfer accountPrivate to smart contract SALES ${amountPrivateSales}`, async () => {
            coinInstance = await TOKEN.deployed(accountPrivateSales);
            let total  = await coinInstance.balanceOf(accountPrivateSales);
            await coinInstance.approve(contractInstance.address, total.toString(), {from: accountPrivateSales});
            await coinInstance.transfer(contractInstance.address, total.toString(), {from: accountPrivateSales})

            total  = await coinInstance.balanceOf(contractInstance.address);            
            expect(web3.utils.fromWei(total)).to.be.equal(amountPrivateSales);
        });
        it(`Verifiy amount in account private to be equal 0`, async () => {
            let total  = await coinInstance.balanceOf(accountPrivateSales);
           
            expect(web3.utils.fromWei(total)).to.be.equal("0");
        });
        it(`Buy with account Investor1 2 ether = 6000 tokens`, async () => {
            let response  = await contractInstance.buyTokens({from: investor1, value: 1, gas: 200000})
            console.log(response);
            // expect(web3.utils.fromWei(total)).to.be.equal("0");
        });
    });
})

1 Answer 1

0

The error is pretty self explanatory: your Sales contract does not have sufficient balance of your token to send it. You need to either manually send your contract some of your tokens, or have your token's contract mint tokens to the sales contract upon deployment. You can do this pretty easily with OpenZeppelin.

1
  • Thanks for the answer, but no. I have already sent my tokens for the contract, including when I print the values I have at the contract address 10millions.
    – Crazy
    Nov 17, 2021 at 14:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.