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.