This code supposedly works. Its supposed to let the owner withdrawal collected ERC20 tokens in a contract.

It calls the balanceOf() for the erc20, then calls transfer().

Only have this error when calling the ERC20 contract from within my contract. ie: Withdrawal() and stake().

The withdrawal works - but in remix, there is never anything returned instead it just says -

transact to BullionixGenerator.withdrawal pending ...

Here is the code:

pragma solidity >=0.4.22 <0.6.0;

import './ERC721Full.sol';
import './Ownable.sol';
import './IERC721Enumerable.sol';
import './IERC721Metadata.sol';
import './ERC721MetadataMintable.sol';
import './SafeMath.sol';
import './IERC20.sol';

contract BullionixGenerator is ERC721Enumerable, ERC721MetadataMintable, Ownable{

    modifier isActive{
    require(isOnline == true);
using SafeMath for uint256;
* @dev Beginning state and init values
IERC20 dgx; 
bool public isOnline = false;
address public DGXContract = address(0x178b11b1a9d8f022987650b7e549DD84A95a1C29); //To be filled in
uint256 public DGXFees = 0; //To be filled in
string public name = "Bullionix";
string public title = "";  //To be filled in
string public symbol = ""; //To be filled in
string public version = "Bullionix v0.1";
string public preURL = "https://bullionix.io/metadata/"; //metadata url to save gas
mapping(uint256 => uint256) public StakedValue;
mapping(uint256 => seriesData) public seriesToTokenId;
struct seriesData {
                string url;
                uint256 numberInSeries;
                uint256 DGXcost;
                uint256 fee;

* @dev Constructor() and storge init
* @dev Constructor, Sets state
constructor() public ERC721Metadata(name, symbol){
        if (address(DGXContract) != address(0x0)) {
            isOnline = true;
            dgx = IERC20(DGXContract);

event NewSeriesMade(string indexed url, uint256 indexed numberToMint);
event Staked(address indexed _sender, uint256 indexed _amount, uint256 indexed tokenStaked);
event Burned(address indexed _sender,  uint256 indexed _amount, uint256 indexed _tokenId);
event Withdrawal(address indexed _receiver,  uint256 indexed _amount);


        - Allow for admin to make new data series
        - Create asset to series

* @dev changes online status to disable contract, must be current owner
 function toggleOnline() external onlyOwner {
         isOnline = !isOnline;
     * @dev Create a new series of NFTs.
     * @param _url location of metadata on backend server. Will be tacked onto the end of set url using returnURL().
     * @param numberToMint  The token number for this series. 10 would make 10 tokens avaliable 
     * @param DGXcost The amount of DGX to send
     * @param _fee Bullionix fee for generation
     * @return A boolean that indicates if the operation was successful.
 function createNewSeries(string memory _url, uint256 numberToMint, uint256 DGXcost, uint256 _fee) public onlyOwner isActive returns (bool _success){
      //takes input from admin to create a new nft series. Will have to define how many tokens to make, how much DGX they cost, and the url from s3.
      require(msg.sender == owner(), 'Only Owner'); //optional as onlyOwner Modifier is used 
      uint256 total = totalSupply();
      for(uint i = 0; i < numberToMint; i++){
          seriesToTokenId[total.add(i)].url = _url;
          seriesToTokenId[total.add(i)].numberInSeries = numberToMint;
          seriesToTokenId[total.add(i)].DGXcost = DGXcost;
          seriesToTokenId[total.add(i)].fee = _fee;

   emit NewSeriesMade(_url, numberToMint);
   return true;

* @dev Stake to series and mint tokens 
 function stake(uint256 _tokenToBuy) public payable isActive returns (bool){
      //takes input from admin to create a new nft series. Will have to define how many tokens to make, how much DGX they cost, and the url from s3.
      require(seriesToTokenId[_tokenToBuy].fee >= 0, "Doesn't Exist yet!");
      uint256  totalCost = seriesToTokenId[_tokenToBuy].DGXcost.add(seriesToTokenId[_tokenToBuy].fee);
      _transferFrom(msg.sender, totalCost);
     string memory fullURL = returnURL(_tokenToBuy);
     require(mintWithTokenURI(msg.sender, _tokenToBuy, fullURL));
     emit Staked(msg.sender, totalCost, _tokenToBuy);
     return true;

     * @dev Burns a specific ERC721 token and refunds user the DGX on the NFT
     * @param tokenId uint256 id of the ERC721 token to be burned.

     //TODO: Finalize this function and transfer the DGX back to msg.sender for burning their nft 
function burn(uint256 tokenId) external {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721Burnable: caller is not owner nor approved");

     * @dev Withdrawals DGX from the balance collected via fees.
function withdrawal() onlyOwner
  returns (bool){
    require(isOnline == false);
    uint256 temp = _checkBalance(); //calls checkBalance which will revert if no balance, if balance pass it into transfer as amount to withdrawal MAX
    require(dgx.transfer(msg.sender, temp)); 
    emit Withdrawal(msg.sender, temp);
    return true;    
function _checkBalance() internal view returns (uint256){
    uint256 tempBalance = dgx.balanceOf(address(this)); //checking balance on DGX contract
   // require(tempBalance > 0, "Revert: Balance is 0!");  //do I even have a balance? Lets see. If no balance revert. 
    return tempBalance;  //here is your balance! Fresh off the stove. 
  * @dev Gets the total amount of tokens owned by the sender
  * @return uint[] with the id of each token owned
function viewYourTokens() external view  returns (uint256[] memory _yourTokens){
       return super._tokensOfOwner(msg.sender);

// Internals 
  * TransferForm called after user has approved DGX to be spent by this contract.
  * If transferform fails, return false 
  * @dev returns the entire tokenURI 
  * @return uint256 with the id of the token

  * @dev returns the entire tokenURI 
  * @return uint256 with the id of the token
function returnURL(uint256 _tokenId) internal view returns (string memory _URL){
   require(returnSeriesURL(_tokenId), "ERC721: approved query for nonexistent token"); //Does this token exist? Lets see. 
   string memory uri = seriesToTokenId[_tokenId].url;
   return string(abi.encodePacked("https://bullionix.io/metadata", uri)); //Here is your URL! 

  * @dev transfer ERC20 token to contract
  * @return true or false if failed
  function returnSeriesURL(uint256 _tokenId) internal view returns (bool){
      string memory temp = seriesToTokenId[_tokenId].url;
      bytes memory tempEmptyStringTest = bytes(temp);
      require(tempEmptyStringTest.length >= 1, temp);
      return true;
 function _transferFrom (address _owner, uint256 _amount)internal returns (bool)

    require(dgx.transferFrom(_owner, address(this), _amount));
    return true;

function() payable external{

tl;dr - code works but remix never returns anything for a receipt. Only with this one function. I've tried commenting out things but I can't find whats causing an issue with remix - note: event was added AFTER the bug, so its not from the indexed event params.

  • please provide the whole contract code, what is ERC20 here? – Igor Sobolev Sep 11 at 10:47
  • Its an openzeppelin erc20 dummy token to transfer. Here is the whole code on the new edit – Zach Sep 12 at 6:09
  • You say ERC20 but you have imports with ERC721? – Niklas Feurstein Sep 14 at 8:13
  • Do you have the transaction hash? I think it might be some temporary network issue, gas price too low or not enough funds to pay tx fee. If there was an error remix will show a transaction failure, but pending means it is waiting for the tx to be confirmed. – Ismael Sep 15 at 4:00
  • @NiklasFeurstein Its a 721 that uses erc20s to pay fees. – Zach Sep 15 at 4:42

Your Answer

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

Browse other questions tagged or ask your own question.