0

I'm experiencing a challenge and hoping for some guidance/help/assist... I've been working on implementing price feed. Testing locally with hardcoded return price works like a charm, no issues. When deployed on testnet (Rinkeby) with actual price fetching data, the price shows in console like it should. However, when I use a function that relies on the price feed, I get an error in Metamask. When I approve it with an error (in the hope of seeing what the issue is), console returns an error that it's run out of gas, however gas limit is not set (if you set the gas limit, no error shows in Metamask and it still runs out of gas, no matter what limit you set). Any help and insights would be greatly appreciated and here is some code to help you help me...

I start with basically importing the price feed:

interface AggregatorV3Interface {

  function decimals() external view returns (uint8);
  function description() external view returns (string memory);
  function version() external view returns (uint256);

  function getRoundData(uint80 _roundId) external view returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

  function latestRoundData() external view returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

}

I have a function where I can fetch the data:

 function getOracleUsdPrice(address token) public view returns (int256, uint256) {
        address oracleAddress = availableOracles[token];
        require(oracleAddress != address(0), "Mp: Token not supported.");

        (, int256 answer, , uint256 updatedAt, ) = AggregatorV3Interface(oracleAddress).latestRoundData();
        return (answer, updatedAt);
        // for local testing ONLY
        // return (100000000, now); //1 for 1 exchange
    }

and then I have a function where I can add the tokens and oracles as needed:

function addOracle(address token, address oracle) public onlyOwner{
        availableOracles[token] = oracle;
}

Inside the failing function, here is what I have:

function buy(IERC20 token, uint256 tokenId) public payable {
        Offer storage offer = offerDetails[tokenId];  

        // get price conversion
        (int256 currentPrice, uint256 updatedAt) = (getOracleUsdPrice(address (token)));

        // convert USD price to crypto
        uint256 cryptoPrice = offer.price.mul(1 ether).div(uint(currentPrice));

        // transfer funds from buyer
        token.universalTransferFromSenderToThis(cryptoPrice);
        
        // pay the seller
        token.universalTransfer(offer.seller, cryptoPrice);
        
        // transfer token to buyer
        _houseToken.safeTransferFrom(offer.seller, msg.sender, tokenId);

        // remove and emit
        delete offerDetails[tokenId];
        emit MarketTransaction("Token purchased", msg.sender, tokenId);
    }

The price conversion is so that when item is listed for USD, user can see the USD price but then purchase with crypto.

I have checked that I have Rinkeby address for both token and oracle address. Transaction fails whether I use ETH or ERC20. I get the same issue on both Rinkeby and Kovan. When I re-deploy on both networks with hardcoded return numbers (like I had in ganache), it goes through. The part that stumps me is that I use the same getOracleUsdPrice() function on the front end (where console and GUI show correct price and conversion).

Thank you in advance for your help and if anything else is missing that you believe would be useful to provide an assist, please let me know. Supper appreciate your help with this.

2
  • Could you add a sample failing token and address that you're using? At first glance, it looks like you're doing everything right. Apr 3, 2021 at 15:05
  • I was testing with test ETH and DAI... the challenge, as I described in solution was the number I kept passing on and the updatedAt. Thanks for taking time to look and respond.
    – Nev
    Apr 7, 2021 at 12:47

1 Answer 1

0

Solved! In case others encounter the same issue and can't find answers, here is what the issue was.

There were two issues:

  1. front end
  2. contract

Front end: to properly display prices I passed the conversion toFixed() and kept passing that number onto the purchase function. This was sending incorrect amount to the function which is why it was failing.

Contract: I used time of when the oracle delivered the price to ensure it's up to date. Sadly the testnet prices are not updated as often as we'd like (aside from ETH). Once I commented that out and ran it with full price from oracle it all worked.

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.