0

I'm trying to get buyToken() to update the balance of the caller. I'm using Truffle and Ganache, running tests, but the testBuyToken() function keeps failing, apparently the BALANCES variable isn't changing and neither is the CIRCULATING_SUPPLY.

Is this because address(this) in TestBasicToken.sol is different than msg.sender in BasicToken.sol? Is this because it can't update the variables quickly enough before the assert attempts to run? Or is there something else I'm fundementally misunderstanding. The two other tests work fine, I'm guessing it has something to do with the fact that this function is payable.

TestBasicToken.sol

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/BasicToken.sol";

contract TestBasicToken{
   uint public inintialBalance = 10**17 * 10;

   address payable Owner = 0x65727c4c3869EA9BbB3BE13613F0a2Fd37e28259;
   address contractAddress = address(this);
   BasicToken basicToken = new BasicToken(Owner);

   uint expectedSupply = 0;
   uint expectedBalance = 300;


   function testTotalSupply() public {
      uint _totalSupply = basicToken.totalSupply();
      Assert.equal(expectedSupply, _totalSupply, "Expected supply should match return value");
   }
   function testBalanceOf() public {
      uint _balance = basicToken.balanceOf(Owner);
      Assert.equal(expectedBalance, _balance, "Expected balance should match return value");
   }
   function testBuyToken() public {
      basicToken.buyToken.value(10**17);
      uint _balance = basicToken.balanceOf(contractAddress);
      Assert.notEqual(0, _balance, "Balance should no longer be 0");
   }
}

BasicToken.sol

pragma solidity ^0.5.3;

contract BasicToken {
   uint MAX_SUPPLY = 1000;
   uint OWNER_SUPPLY = 300;
   uint CIRCULATING_SUPPLY = 0;

   address payable public BASIC_TOKEN_ETH_WALLET;
   uint TOKEN_PRICE;

   mapping(address => mapping(address => uint)) APPROVED;
   mapping(address => uint) BALANCES;

   event SupplyChangeEvent(uint NewBalance, uint NewSupply);

   constructor(address payable eth_wallet) public {
      BASIC_TOKEN_ETH_WALLET = eth_wallet;
      BALANCES[BASIC_TOKEN_ETH_WALLET] = OWNER_SUPPLY;
   }

   //********************ERC20 TOKEN FUNCTIONS********************************
   function totalSupply() public view returns(uint _total_supply) {
      return CIRCULATING_SUPPLY;
   }
   function balanceOf(address _owner) public view returns (uint balance){
      return BALANCES[_owner];  
   }
   function transfer(address _to, uint _value) public returns (bool success){

      if( _value < 0 || _value > BALANCES[msg.sender]) return false;

      BALANCES[msg.sender] -= _value;
      BALANCES[_to] += _value;

      return true;
   }
   function approve(address _spender, uint _value) public returns (bool success) {
      if( _value <= 0 || _value > BALANCES[msg.sender]) return false;

      APPROVED[msg.sender][_spender] = _value;

      return true;
   }
   function allowance(address _owner, address _spender) public view returns(uint remaining){
      return APPROVED[_owner][_spender];
   }
   function transferFrom(address _from, address _to, uint _value) public returns (bool success){
      if(_value <= 0 || _value > allowance(_from, msg.sender) || _value > BALANCES[_from])
         return false;

      BALANCES[_from] -= _value;
      APPROVED[_from][msg.sender] -= _value;
      BALANCES[_to] += _value;

      return true;
   }
   //****************************************************************************
   function buyToken() public payable{
      CIRCULATING_SUPPLY += 1;
      BALANCES[msg.sender] += 1;
      emit SupplyChangeEvent(BALANCES[msg.sender], CIRCULATING_SUPPLY);
      /*
      uint tokenAmount = (msg.value)/(10**17);
      uint returningValue = 0;
      uint availableSupply = MAX_SUPPLY - CIRCULATING_SUPPLY - OWNER_SUPPLY;
      if(tokenAmount > availableSupply){
         tokenAmount = availableSupply;
         returningValue = msg.value - tokenAmount * 10**17;
      }

      msg.sender.transfer(returningValue);
      BASIC_TOKEN_ETH_WALLET.transfer(msg.value - returningValue);
      BALANCES[msg.sender] += 1;
      CIRCULATING_SUPPLY += tokenAmount;
     */
   }
}

Output from running truffle test

2 passing (5s)   1 failing

  1) TestBasicToken
       testBuyToken:
     Error: Balance should no longer be 0 (Tested: 0, Against: 0)
      at /usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/testing/soliditytest.js:71:1
      at Array.forEach (<anonymous>)
      at processResult (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/testing/soliditytest.js:69:1)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)
3
  • Function buyToken increases the balance of the account used for calling this function. Function testBuyToken checks the balance of your test contract (which I would imagine is different from that account). Oct 26, 2019 at 6:15
  • You say buyTokens, but the function is buyToken. Which one is it? Oct 26, 2019 at 20:40
  • Thank you, I've updated it, they should all be buyToken. Oct 26, 2019 at 23:50

1 Answer 1

1

tl;dr: your line should read:

basicToken.buyToken.value(10**17)();

Explanation: basicToken.buyToken.value(10**17); looks like you are calling the buyToken function, but it is not calling it. The .value thing is a function call modifier. So when you do buyToken.value(10**17), what you are asking is please modify my function call by passing value along with it. After that you need to call the function for real. And so add ().

3
  • Okay, I think I get it, I had tried that before but kept getting an error. After trying it now I'm still getting the same error: Error: Returned error: VM Exception while processing transaction: revert Oct 27, 2019 at 0:00
  • @EduardoGutierrez You need to have some ether in the test contract. Check the truffle documentation how to do that trufflesuite.com/docs/truffle/testing/…
    – Ismael
    Oct 27, 2019 at 2:05
  • @Ismael Thank you so much! I thought I had followed these steps initially which is why I was doing things I shouldn't have. My posted code has a typo 'initinalBalance' instead of initialBalance. Oct 27, 2019 at 2:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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