Feed de precios de Chainlink: la función falla cuando el precio no está codificado pero se muestra correctamente en la consola

Estoy experimentando un desafío y espero alguna orientación/ayuda/asistencia... He estado trabajando en la implementación de feeds de precios. Las pruebas locales con el precio de devolución codificado funcionan de maravilla, sin problemas. Cuando se implementa en testnet (Rinkeby) con datos de obtención de precios reales, el precio se muestra en la consola como debería. Sin embargo, cuando uso una función que se basa en el feed de precios, aparece un error en Metamask. Cuando lo apruebo con un error (con la esperanza de ver cuál es el problema), la consola devuelve un error de que se quedó sin gasolina, sin embargo, el límite de gasolina no está establecido (si establece el límite de gasolina, no se muestra ningún error en Metamask y todavía se queda sin gasolina, sin importar el límite que establezca). Cualquier ayuda e información sería muy apreciada y aquí hay un código para ayudarlo a ayudarme ...

Comienzo básicamente importando el feed de precios:

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
    );

}

Tengo una función donde puedo obtener los datos:

 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
    }

y luego tengo una función donde puedo agregar los tokens y los oráculos según sea necesario:

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

Dentro de la función que falla, esto es lo que tengo:

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);
    }

La conversión de precio es para que cuando el artículo esté listado en USD, el usuario pueda ver el precio en USD pero luego comprar con criptografía.

He comprobado que tengo la dirección de Rinkeby tanto para el token como para la dirección de Oracle. La transacción falla si uso ETH o ERC20. Tengo el mismo problema tanto con Rinkeby como con Kovan. Cuando vuelvo a implementar en ambas redes con números de retorno codificados (como tenía en ganache), pasa. La parte que me deja perplejo es que utilizo la misma función getOracleUsdPrice() en el front-end (donde la consola y la GUI muestran el precio y la conversión correctos).

Gracias de antemano por su ayuda y si falta algo más que cree que sería útil para proporcionar una ayuda, hágamelo saber. Cena agradezco tu ayuda con esto.

¿Podría agregar un token fallido de muestra y la dirección que está utilizando? A primera vista, parece que lo estás haciendo todo bien.
Estaba probando con ETH y DAI de prueba... el desafío, como describí en la solución, era el número que seguí transmitiendo y el At actualizado. Gracias por tomarse el tiempo para mirar y responder.

Respuestas (1)

¡Resuelto! En caso de que otros encuentren el mismo problema y no puedan encontrar respuestas, este es el problema.

Había dos problemas:

  1. Interfaz
  2. contrato

Front-end: para mostrar correctamente los precios, pasé la conversión aFixed() y seguí pasando ese número a la función de compra. Esto estaba enviando una cantidad incorrecta a la función, por lo que estaba fallando.

Contrato: utilicé el momento en que el oráculo entregó el precio para asegurarme de que esté actualizado. Lamentablemente, los precios de la red de prueba no se actualizan con la frecuencia que nos gustaría (aparte de ETH). Una vez que comenté eso y lo ejecuté con el precio completo de Oracle, todo funcionó.