Crowdsale: revert when buying tokens

using openzeppelin-solidity to create crowdsale.
Then I use this statement to Buy Token

MyCrowdsaleInstance.sendTransaction({ 
   from: purchaser[1], 
   value: web3.utils.toWei("0.5", "ether"), 
   gas: "220000"
})

And I got the error!

    Error: Returned error: VM Exception while processing transaction: revert
    at XMLHttpRequest._onHttpResponseEnd (C:\Users\zx\AppData\Roaming\nvm\v10.15.1\node_modules\truffle\build\webpack:\~\xhr2-cookies\dist\xml-http-request.js:318:1)
    at XMLHttpRequest._setReadyState (C:\Users\zx\AppData\Roaming\nvm\v10.15.1\node_modules\truffle\build\webpack:\~\xhr2-cookies\dist\xml-http-request.js:208:1)
    at XMLHttpRequestEventTarget.dispatchEvent (C:\Users\zx\AppData\Roaming\nvm\v10.15.1\node_modules\truffle\build\webpack:\~\xhr2-cookies\dist\xml-http-request-event-target.js:34:1)
    at XMLHttpRequest.request.onreadystatechange (C:\Users\zx\AppData\Roaming\nvm\v10.15.1\node_modules\truffle\build\webpack:\~\web3\~\web3-providers-http\src\index.js:96:1)
    at C:\Users\zx\AppData\Roaming\nvm\v10.15.1\node_modules\truffle\build\webpack:\packages\truffle-provider\wrapper.js:112:1
    at C:\Users\zx\AppData\Roaming\nvm\v10.15.1\node_modules\truffle\build\webpack:\~\web3-eth\~\web3-core-requestmanager\src\index.js:140:1
    at Object.ErrorResponse (C:\Users\zx\AppData\Roaming\nvm\v10.15.1\node_modules\truffle\build\webpack:\~\web3-eth\~\web3-core-helpers\src\errors.js:29:1)

my version:

openzeppelin-solidity: "^2.1.3"
Truffle v5.0.17 (core: 5.0.16)
Solidity v0.5.0 (solc-js)
Node v10.15.1
Web3.js v1.0.0-beta.37

contract code:

// MyToken.sol

pragma solidity ^0.5.0;

import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";

contract MyToken is ERC20, ERC20Detailed {
  uint public INITIAL_SUPPLY = 10000000000;

  constructor(string memory _name, string memory _symbol, uint8 _decimals)
    ERC20Detailed(_name, _symbol, _decimals)
    public
  {
      _mint(msg.sender, INITIAL_SUPPLY);
  }

}

// MyCrowdsale.sol

pragma solidity ^0.5.0;

import './MyToken.sol';
import "openzeppelin-solidity/contracts/crowdsale/Crowdsale.sol";

contract MyCrowdsale is Crowdsale {
  constructor(
      uint256 rate,    // rate in TKNbits
      address payable wallet,
      MyToken token
  )
      Crowdsale(rate, wallet, token)
      public
  {

  }

}

// 2_deploy_token.js

const MyToken = artifacts.require("MyToken");
const MyCrowdsale = artifacts.require("MyCrowdsale");

module.exports = function(deployer, network, accounts) {
  const _name = "My Token";
  const _symbol = "MTK";
  const _decimals = 2;

  const rate = 1;
  const wallet = accounts[0];
  return deployer.then(() => {
    return deployer.deploy(MyToken, _name, _symbol, _decimals);
  }).then(() => {
    return deployer.deploy(
      MyCrowdsale,
      rate,
      wallet,
      MyToken.address
    );
  })
};
1 Like

Hi @shellteo

It looks there are not enough tokens to fulfill buyTokens.

Check crowd sale token balance

Does the crowdsale contract have any tokens?
In the code you provided, the MyToken contract mints 10,000,000,000 token (base units) to the deployer (msg.sender) whilst the crowdsale contract has zero tokens.

You could transfer the total supply minted to the crowdsale contract.

In Truffle Console you can do the following:

const myCrowdsale = await MyCrowdsale.deployed()
const myToken = await MyToken.deployed()
await myToken.transfer(myCrowdsale.address, await myToken.totalSupply())

Check rate and available tokens

The second thing to look at is the rate and the available tokens.

The rate is set to 1 which means 1 wei buys 1 token (base unit).
0.5 Ether gets 0.5 * 10**18 token base units, which even once the total supply is transferred to the crowdsale contract is more than the total supply of tokens.

Using a rate of 1, 10 gwei would get 10 * 10**9 token base units (the total supply).

await myCrowdsale.sendTransaction({value: web3.utils.toWei('10', 'gwei'), gas: '220000'})

Rate is covered in the following:

It doesn’t work, I try transfer and approve method, also has error Error: Returned error: VM Exception while processing transaction: revert

await myToken.transfer(myCrowdsale.address, await myToken.totalSupply())
await myToken.approve(myCrowdsale.address,   await myToken.totalSupply())
1 Like

Hi @shellteo

You can do the transfer as part of the deploy (see deploy below) if that is easier.

The MyToken contract mints tokens to the deployer of the contract, so if you call a transfer, it needs to be from the account that deployed the MyToken contract.

Updated deploy with transfer of total supply to crowdsale contract

const MyToken = artifacts.require("MyToken");
const MyCrowdsale = artifacts.require("MyCrowdsale");

module.exports = async function(deployer, network, accounts) {
  const _name = "My Token";
  const _symbol = "MTK";
  const _decimals = 2;

  const rate = 1;
  const wallet = accounts[0];
  await deployer.deploy(MyToken, _name, _symbol, _decimals);
  await deployer.deploy(MyCrowdsale, rate, wallet, MyToken.address);

  const myCrowdsale = await MyCrowdsale.deployed();
  const myToken = await MyToken.deployed()
  await myToken.transfer(myCrowdsale.address, await myToken.totalSupply());
};

You can then purchase tokens

await myCrowdsale.sendTransaction({value: web3.utils.toWei('10', 'gwei'), gas: '220000'})

As per my previous reply, the current rate and token supply means that the maximum value of tokens that can be purchased is 10 gwei. To change this, change either the rate or the token supply or both.

Hi @shellteo have you resolved your issue with the crowdsale? Let me know if you have more questions.

1 Like