0

I am calling ERC20.transfer inside of ERC721 contract. I have no problem in compiling and migrating it, but when that line of code is executed, metamask is throwing an error.

Here is my code:

The line causing the error: Erc20Contract.transfer(nftInfo[from].creator, 10)

ERC721

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

import "../openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";
import "../openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";
import "../openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol";
import "../openzeppelin-contracts/contracts/math/SafeMath.sol";
import "../openzeppelin-contracts/contracts/utils/Address.sol";
import "../openzeppelin-contracts/contracts/utils/Counters.sol";
import "./ERC20Token.sol";

contract NFTtoken is ERC721 {
    using SafeMath for uint256;
    using Address for address;
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    ERC20Token Erc20Contract;

    constructor(address tokenAddress) ERC721("NC NFT example", "NCNFT") {
        owner = msg.sender;
        decimals = 0;
        Erc20Contract = ERC20Token(tokenAddress);
    }
    function transferNFT(address from, address to, uint256 tokenId)  public returns (bool){
        transferFrom(from, to, tokenId);
        Erc20Contract.transfer(nftInfo[from].creator, 10);
        //^^^^^^^^^ this line is causing an errror. 
    }
}

ERC20

// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "../openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "../openzeppelin-contracts/contracts/math/SafeMath.sol";

contract ERC20Token is IERC20 {
    function transfer(address to, uint256 tokens) public override returns (bool) {
        balances[msg.sender] = SafeMath.sub(balances[msg.sender], tokens);
        balances[to] = SafeMath.sub(balances[to], tokens);
        emit Transfer(msg.sender, to, tokens);
        return true;
    }
}

2_deploy_contracts.js

const NFTtoken = artifacts.require("NFTtoken");
const ERC20token = artifacts.require("ERC20Token")
let _totalSupply = 20000;

module.exports = function(deployer) {
    deployer.deploy(ERC20token, _totalSupply, web3.utils.toWei('0.01', 'ether'), [web3.utils.asciiToHex('Rama'), web3.utils.asciiToHex('Nick'), web3.utils.asciiToHex('Jose')]); 
    deployer.deploy(NFTtoken, ERC20token.address);
};

error:

MetaMask - RPC Error: [ethjs-query] 
while formatting outputs from RPC 
'{"value":{"code":-32603,"data":{"message":"VM Exception while processing transaction: revert",
"code":-32000,"data": {"0x18abb17dda4df83e94eb19c0db814e9d4d3ec65a5f96001c0597fb9e93f1a816":{"error":"revert","program_counter":4807,"return":"0x"},
"stack":"RuntimeError: VM Exception while processing transacti
on: revert\n    at Function.RuntimeError.fromResults (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\utils\\runtimeerror.js:94:13)\n    at BlockchainDouble.processBlock (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\blockchain_double.js:627:24)\n    at runMicrotasks (<anonymous>)\n    at processTicksAndRejections (internal/process/task_queues.js:93:5)","name":"RuntimeError"}}}}' {code: -32603, message: `[ethjs-query] while formatting outputs from RPC '{…/task_queues.js:93:5)","name":"RuntimeError"}}}}'`}

Uncaught (in promise) {code: -32603, message: `[ethjs-query] while formatting outputs from RPC '{…/task_queues.js:93:5)","name":"RuntimeError"}}}}'`, 
stack: '{\n  "code": -32603,\n  "message": "[ethjs-query] wh…gaeaoehlefnkodbefgpgknn/background-0.js:1:216902)'}

1 Answer 1

2

Assuming that your NFTtoken has enough balance of your ERC20 token (as you are transferring 10 tokens from the NFT contract to the NFT creator), I would say your implementation of the transfer method on the ERC20 contract is not correct.

As you are transferring tokens to the to address you should add the amount to the to balance instead of substracting it:

// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "../openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "../openzeppelin-contracts/contracts/math/SafeMath.sol";

contract ERC20Token is IERC20 {
    function transfer(address to, uint256 tokens) public override returns (bool) {
        balances[msg.sender] = SafeMath.sub(balances[msg.sender], tokens);
        balances[to] = SafeMath.add(balances[to], tokens);
        emit Transfer(msg.sender, to, tokens);
        return true;
    }
}
1
  • Hi Richard, that wasn't the cause of the error, but nice catch! Thank you for your comment.
    – Nayana
    Jan 14, 2022 at 1:08

Your Answer

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

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