[Ethereum] Truffle Error- VM Exception while processing transaction: revert

soliditytruffle

I create a smart contract to sell my token.I am following the Dapp University(youtube channel) course.

I have done unit testing of smart contract.All test cases pass.

And I am trying to buy token on my client side application.So there is transaction failed.And this error comes VM Exception while processing transaction: revert:

Then I test buyTokens() function in truffle console.So,The same error comes.

Here is my solidity code:-

pragma solidity ^0.4.2;

import "./DappToken.sol";

    contract DappTokenSale {
        address admin;
        DappToken public tokenContract;
        uint256 public tokenPrice;
        uint256 public tokensSold;

        event Sell(address _buyer, uint256 _amount);

        function DappTokenSale(DappToken _tokenContract, uint256 _tokenPrice) public {
            admin = msg.sender;
            tokenContract = _tokenContract;
            tokenPrice = _tokenPrice;
        }

        function multiply(uint x, uint y) internal pure returns (uint z) {
            require(y == 0 || (z = x * y) / y == x);
        }

        function buyTokens(uint256 _numberOfTokens) public payable {
            require(msg.value == multiply(_numberOfTokens, tokenPrice));
            require(tokenContract.balanceOf(this) >= _numberOfTokens);
            require(tokenContract.transfer(msg.sender, _numberOfTokens));

            tokensSold += _numberOfTokens;

            Sell(msg.sender, _numberOfTokens);
        }

      // Ending Token DappTokenSale
        function endSale() public {
                // Require admin
                require (msg.sender == admin);

                 // Transfer remaing DappToken to admin
                require(tokenContract.transfer(admin,tokenContract.balanceOf(this)));


                // Destroy Contract
                selfdestruct(admin);

        }
 }

Here is my "DappToken" solidity code:-

pragma solidity ^0.4.2;

/**
 * The contractName contract does this and that...
 */
contract DappToken {
    // Name
    string public name = "DappToken";
    // Symbol
    string public symbol = 'DAPP';
    //standard
    string public standard = 'DApp Token v1.0';
    uint256 public totalSupply;

    event Transfer(
        address indexed _form,
        address indexed _to,
        uint256 _value
        );

    event Approval(
            address indexed _owner,
            address indexed _spender,
            uint256 _value
        );


    mapping(address => uint256) public balanceOf;
    mapping(address => mapping (address => uint256)) public allowance;


    function DappToken (uint256 _intialSupply) public {
        balanceOf[msg.sender] = _intialSupply;
        totalSupply = _intialSupply;
        //allcate the intial supply

    }   

    //Transfar
    function transfer(address _to,uint256 _value) public returns (bool success){
    // Exception if account does not enough
    require (balanceOf[msg.sender] >= _value);
    // Transfar the balance
    balanceOf[msg.sender] -= _value;
    balanceOf[_to] += _value; 

    // Transfar Event
    Transfer(msg.sender,_to,_value);

    // Return a boolean
    return true;
    } 

    // approve
    function approve(address _spender,uint256 _value) public returns (bool success){
        //allowence
        allowance[msg.sender][_spender] = _value;

        // Approve event
        Approval(msg.sender,_spender,_value);


             return true;

    }
    // transfer form
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        require(_value <= balanceOf[_from]);
        require(_value <= allowance[_from][msg.sender]);
        // change the balance
        balanceOf[_from] -= _value;

        //update the balance
       balanceOf[_to] += _value; 

       allowance[_from][msg.sender] -= _value;

       emit Transfer(_from,_to,_value);


        return true;
    }
}

Here is my "test.js" code:-

var DappToken = artifacts.require('./DappToken.sol');
var DappTokenSale = artifacts.require('./DappTokenSale.sol');

contract('DappTokenSale', function(accounts) {
  var tokenInstance;
  var tokenSaleInstance;
  var admin = accounts[0];
  var buyer = accounts[1];
  var tokenPrice = 1000000000000000; // in wei
  var tokensAvailable = 750000;
  var numberOfTokens;

  it('initializes the contract with the correct values', function() {
    return DappTokenSale.deployed().then(function(instance) {
      tokenSaleInstance = instance;
      return tokenSaleInstance.address
    }).then(function(address) {
      assert.notEqual(address, 0x0, 'has contract address');
      return tokenSaleInstance.tokenContract();
    }).then(function(address) {
      assert.notEqual(address, 0x0, 'has token contract address');
      return tokenSaleInstance.tokenPrice();
    }).then(function(price) {
      assert.equal(price, tokenPrice, 'token price is correct');
    });
  });

  it('facilitates token buying', function() {
    return DappToken.deployed().then(function(instance) {
      // Grab token instance first
      tokenInstance = instance;
      return DappTokenSale.deployed();
    }).then(function(instance) {
      // Then grab token sale instance
      tokenSaleInstance = instance;
      // Provision 75% of all tokens to the token sale
      return tokenInstance.transfer(tokenSaleInstance.address, tokensAvailable, { from: admin })
    }).then(function(receipt) {
      numberOfTokens = 10;
      return tokenSaleInstance.buyTokens(numberOfTokens, { from: buyer, value: numberOfTokens * tokenPrice })
    }).then(function(receipt) {
      assert.equal(receipt.logs.length, 1, 'triggers one event');
      assert.equal(receipt.logs[0].event, 'Sell', 'should be the "Sell" event');
      assert.equal(receipt.logs[0].args._buyer, buyer, 'logs the account that purchased the tokens');
      assert.equal(receipt.logs[0].args._amount, numberOfTokens, 'logs the number of tokens purchased');
      return tokenSaleInstance.tokensSold();
    }).then(function(amount) {
      assert.equal(amount.toNumber(), numberOfTokens, 'increments the number of tokens sold');
      return tokenInstance.balanceOf(buyer);
    }).then(function(balance) {
      assert.equal(balance.toNumber(), numberOfTokens);
      return tokenInstance.balanceOf(tokenSaleInstance.address);
    }).then(function(balance) {
      assert.equal(balance.toNumber(), tokensAvailable - numberOfTokens);
      // Try to buy tokens different from the ether value
      return tokenSaleInstance.buyTokens(numberOfTokens, { from: buyer, value: 1 });
    }).then(assert.fail).catch(function(error) {
      assert(error.message.indexOf('revert') >= 0, 'msg.value must equal number of tokens in wei');
      return tokenSaleInstance.buyTokens(800000, { from: buyer, value: numberOfTokens * tokenPrice })
    }).then(assert.fail).catch(function(error) {
      assert(error.message.indexOf('revert') >= 0, 'cannot purchase more tokens than available');
    });
  });

  it('ends token sale', function() {
    return DappToken.deployed().then(function(instance) {
      // Grab token instance first
      tokenInstance = instance;
      return DappTokenSale.deployed();
    }).then(function(instance) {
      // Then grab token sale instance
      tokenSaleInstance = instance;
      // Try to end sale from account other than the admin
      return tokenSaleInstance.endSale({ from: buyer });
    }).then(assert.fail).catch(function(error) {
      assert(error.message.indexOf('revert' >= 0, 'must be admin to end sale'));
      // End sale as admin
      return tokenSaleInstance.endSale({ from: admin });
    }).then(function(receipt) {
      return tokenInstance.balanceOf(admin);
    }).then(function(balance) {
      assert.equal(balance.toNumber(), 999990, 'returns all unsold dapp tokens to admin');
      // Check that token price was reset when selfDestruct was called
    //   return tokenSaleInstance.tokenPrice();
    // }).then(function(price) {
    //   assert.equal(price.toNumber(), 0, 'token price was reset');
    });
  });

});

I am new in this field.What is this error mean and why this error comes??Any one tell me What I mistake in code??.

Best Answer

it could be a token provision issue: dappTokenSale contract address doesn't have any DAPP token being provisioned yet, which results to this following line of code failed in DappTokenSale.sol file

require(tokenContract.balanceOf(this) >= _numberOfTokens);
  1. you can go to truffle console to check if this is the case:
    • type truffle console in the terminal
    • type this in the truffle console, DappToken.deployed().then(function(instance) { return instance.balanceOf(tokenSaleAddress) }) where tokenSaleAddress is displayed when you run truffle migrate --reset
  2. To provision Dapp token, type this in truffle console:DappToken.deployed().then(function(instance) { instance.transfer(tokenSaleAddress, 750000, { from:admin }) }), where admin is the 1st account in Ganche, assuming you are going to provision 750000 out of 1000000 to the tokenSaleAddress
Related Topic