'After truffle test, we are getting this error: rewards tokens for staking: Error: Returned error: VM Exception while processing transaction: revert

All the contracts are compiling but error is depicted only in truffle test.

decentalBank.tests.js

    // const { assert } = require('console')



const RWD = artifacts.require('RWD')
const Tether = artifacts.require('Tether')
const  DecentralBank = artifacts.require('DecentralBank')


require('chai')
.use(require('chai-as-promised'))
.should()

contract('DecentralBank', ([owner, customer]) =>
{
    let tether, rwd, decentralBank

    function tokens(number)
    {
       return web3.utils.toWei(number, 'ether')
    }

    before(async () =>
    {
       //load contracts
       tether = await Tether.new()
       rwd = await RWD.new()
       decentralBank = await DecentralBank.new(rwd.address, tether.address)

       //transfer all tokens to DecentralBank (1 million)
       await rwd.transfer(decentralBank.address, tokens('1000000'))

       //transfer 100 mock tethers to customer
       await tether.transfer(customer, tokens('100'), {from: owner})

    })

  describe('Mock Tether Deployment' , async () =>
  {
     it('matches name successfully', async () =>
     {
        let tether = await Tether.new()
        const name = await tether.name()
        assert.equal(name, 'Tether')
   
     })
  })

  describe('Reward Token', async () =>
  {
     it ('matches name successfully' , async () =>
     {
        let reward = await RWD.new()
        const name = await reward.name()
        assert.equal(name, 'Reward Token')
     })
  })

  describe('Decentral Bank Deployment', async () =>
  {
     it ('matches name successfully' , async () =>
     {
        let reward = await RWD.new()
        const name = await reward.name()
        assert.equal(name, 'Reward Token')
     })
     
      it('contract has tokens', async () =>
      {
         let balance = await rwd.balanceof(decentralBank.address)
         assert.equal(balance, tokens('1000000'))
      })

      describe('Yeild Farming', async () =>
      {
         it('rewards tokens for staking', async () =>
         {
            let result 

            //check investor balance
            result = await tether.balanceof(customer)
            assert.equal(result.toString(), tokens('100'), 'customer mock wallet balance');

            //check staking for customer of 100  tokens
            await tether.approve(decentralBank.address, tokens('100'), {from: customer})
            await decentralBank.depositTokens(tokens('100'), {from: customer})

            //check updated balance of customer
            result = await tether.balanceof(customer)
            assert.equal(result.toString(), tokens('100'), 'customer mock wallet after staking 100 tokens')

            //check updated balance of decentral bank
            result = await tether.balanceof(decentralBank.address)
            assert.equal(result.toString(), tokens('0'), 'decentral bank mock wallet balance after staking')

            //(ACTUAL CODE)
           // check updated balance of customer
            // result = await tether.balanceof(customer)
            // assert.equal(result.toString(), tokens('0'), 'customer mock wallet after staking 100 tokens')

            // //check updated balance of decentral bank
            // result = await tether.balanceof(decentralBank.address)
            // assert.equal(result.toString(), tokens('100'), 'decentral bank mock wallet balance after staking')

            //is staking balance
            result = await decentralBank.isStaking(customer)
            assert.equal(result.toString(), 'true', 'customer is staking status after staking')

            //issue tokens
            await decentralBank.issueTokens({from: owner})

            //ensure only the owner can issue tokens
            await decentralBank.issueTokens({from: customer}).should.be.rejected;

            // //unstake tokens
            await decentralBank.unstakeTokens({from: customer})

            //check unstaking balances
            result = await tether.balanceof(customer)
            assert.equal(result.toString(), tokens('0'), 'customer mock wallet after unstaking ')

            //check updated balance of decentral bank
            result = await tether.balanceof(decentralBank.address)
            assert.equal(result.toString(), tokens('100'), 'decentral bank mock wallet balance after staking')

            //is staking balance
            result = await decentralBank.isStaking(customer)
            assert.equal(result.toString(), 'false', 'customer is no longer staking  after unstaking')


            
         })
      })

  })
})


DecentralBank.sol

    pragma solidity ^0.5.0;

import './RWD.sol';
import './Tether.sol';

contract DecentralBank 
{
    string public name = 'Decentral Bank';
    address public owner; 
    Tether public tether;
    RWD public rwd;

    address[] public stakers;

    mapping(address => uint) public stakingBalance;
    mapping(address => bool) public hasStaked;
    mapping(address => bool) public isStaking;

    constructor(RWD _rwd, Tether _tether) public
    {
      rwd = _rwd;
      tether = _tether;
      owner = msg.sender;
    }

    //staking function
    function depositTokens(uint _amount) public 
    {
      //require staking amount to be greater than zero
      require(_amount > 0 ,'amount cannot be 0');

      //trasfer tether tokens to this contract address for staking
      tether.transferFrom(msg.sender, address(this), _amount);

      //update staking balance
      stakingBalance[msg.sender] = stakingBalance[msg.sender] + _amount;

      if(!hasStaked[msg.sender])
      {
        stakers.push(msg.sender);
      }

      //update staking balance
      isStaking[msg.sender] = true;
      hasStaked[msg.sender] = true;
    }

      //unstake tokens
      function unstakeTokens() public 
      {
        uint balance = stakingBalance[msg.sender];
         //require the amount to be greater then zero
        require(balance > 0, 'Staking balance cant be less than zero');
         //transfer the tokens to the specified contract address from our bank
        tether.transfer(msg.sender, balance);
        //reset staking balance
        stakingBalance[msg.sender] = 0;
        //update staking status
        isStaking[msg.sender] = false;

      }


    //issue rewards
    function issueTokens() public
    {
    //only owner can call this function
    require(msg.sender == owner, 'caller must be the owner');
     for(uint i=0; i<stakers.length; i++)
     {
     address recipient = stakers[i];
     uint balance = stakingBalance[recipient] / 9; //9 to create percentage incentive
     if(balance > 0)
     {
     rwd.transfer(recipient, balance);
     }
     }
}
}

Migrations.sol

    pragma solidity ^0.5.0;

contract Migrations {
    address public owner; 
    uint public last_completed_migration; 

    constructor() public {
        owner = msg.sender;
    }

    modifier restricted(){
        if (msg.sender == owner) _;
    }

    function setCompleted(uint completed) public restricted{
        last_completed_migration = completed; 
    }

    function upgrade(address new_address) public restricted {
        Migrations upgraded = Migrations(new_address); 
        upgraded.setCompleted(last_completed_migration);
    }
}

RWD.sol

    pragma solidity ^0.5.0;

contract RWD {
    string public name = 'Reward Token';
    string public symbol = 'RWD';
    uint256 public totalSupply = 1000000000000000000000000;
    uint decimals = 18;


    event Transfer(
    address indexed _from,
    address indexed _to,
    uint _value 
    );

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

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

    constructor() public
    {
        balanceof[msg.sender] = totalSupply;
    }

    function transfer(address _to, uint _value)public returns (bool success)
    {
        //require that the value is greater or equal  for transfer
        require(balanceof[msg.sender]>=_value);
        //transfer the  amount  and subtract  the balance
        balanceof[msg.sender] -= _value;
        //add the balance
        balanceof[_to] += _value;
        emit Transfer(msg.sender ,_to, _value);
        return true;
    }

    function approve(address _spender,uint256 _value) public returns (bool success)
    {
        allowance[msg.sender][_spender] = _value;   
        emit Approval(msg.sender, _spender, _value);
        return true;
    }
    function transferFrom(address _from, address _to, uint256 _value )public returns (bool success) 
    {
        require(_value <=balanceof[_from]);
         require(_value <=allowance[_from][msg.sender]);
        //add the balance for transactionFrom
        balanceof[_to]+= _value;
        //subtract  the balance  for transactionFrom
        balanceof[_to]-= _value;
        allowance[msg.sender][_from]-= _value;
        emit Transfer(_from ,_to, _value);
         return true;
    }


}

Tether.sol

    pragma solidity ^0.5.0;

contract Tether {
    string public name = 'Tether';
    string public symbol = 'USDT';
    uint256 public totalSupply = 1000000000000000000000000;
    uint decimals = 18;


    event Transfer(
    address indexed _from,
    address indexed _to,
    uint _value 
    );

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

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

    constructor() public
    {
        balanceof[msg.sender] = totalSupply;
    }

    function transfer(address _to, uint _value)public returns (bool success)
    {
        //require that the value is greater or equal  for transfer
        require(balanceof[msg.sender] >= _value);
        //transfer the  amount  and subtract  the balance
        balanceof[msg.sender] -= _value;
        //add the balance
        balanceof[_to] += _value;
        emit Transfer(msg.sender ,_to, _value);
        return true;
    }

    function approve(address _spender, uint256 _value) public returns (bool success)
    {
        allowance[msg.sender][_spender] = _value;   
        emit Approval(msg.sender, _spender, _value);
        return true;
    }
    function transferFrom(address _from, address _to, uint256 _value )public returns (bool success) 
    {
        require(_value <=balanceof[_from]);
        require(_value <=allowance[_from][msg.sender]);
        //add the balance for transactionFrom
        balanceof[_to] += _value;
        //subtract  the balance  for transactionFrom
        balanceof[_to] -= _value;
        allowance[msg.sender][_from] -= _value;
        emit Transfer(_from, _to, _value);
         return true;
    }


}

ERROR: AFTER TRUFFLE TEST COMMAND

  1. Contract: DecentralBank Decentral Bank Deployment Yeild Farming rewards tokens for staking: Error: Returned error: VM Exception while processing transaction: revert at Context. (test\decentalBank.tests.js:98:69) at runMicrotasks () at processTicksAndRejections (node:internal/process/task_queues:96:5)


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source