diff --git a/contracts/test/oracles/default/ChainlinkOracleTest.t.sol b/contracts/test/oracles/default/ChainlinkOracleTest.t.sol index 02431bbec..30e9ea9da 100644 --- a/contracts/test/oracles/default/ChainlinkOracleTest.t.sol +++ b/contracts/test/oracles/default/ChainlinkOracleTest.t.sol @@ -5,8 +5,9 @@ import { ChainlinkPriceOracleV2 } from "../../../oracles/default/ChainlinkPriceO import { ICToken } from "../../../external/compound/ICToken.sol"; import { BaseTest } from "../../config/BaseTest.t.sol"; +import { CoingeckoAPICaller } from "./CoingeckoAPICaller.sol"; -contract ChainlinkOraclesTest is BaseTest { +contract ChainlinkOraclesTest is BaseTest, CoingeckoAPICaller { ChainlinkPriceOracleV2 oracle; address usdcPolygon = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174; @@ -75,4 +76,11 @@ contract ChainlinkOraclesTest is BaseTest { assertApproxEqAbs(usdtPrice, usdcPrice, 1e16, "usd prices differ too much"); } + + function testPriceAgainstCoingecko() public debuggingOnly { + string memory base = "usd"; + string memory asset = "ethereum-classic"; + uint256 price = getCoinGeckoPrice(asset, base); // scaled to 1e18 + emit log_named_uint("ethereum-classic price in usd", price); + } } diff --git a/contracts/test/oracles/default/CoingeckoAPICaller.sol b/contracts/test/oracles/default/CoingeckoAPICaller.sol new file mode 100644 index 000000000..e895fd775 --- /dev/null +++ b/contracts/test/oracles/default/CoingeckoAPICaller.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +import "forge-std/Vm.sol"; +import "forge-std/Test.sol"; + +contract CoingeckoAPICaller is Test { + string internal constant COINGECKO_BASE_URL = "https://api.coingecko.com/api/v3/simple/price?vs_currencies="; + string internal constant PRECISION_QUERY_URL = "&precision=18&ids="; + + function getCoinGeckoPrice(string memory asset, string memory base) internal returns (uint256) { + string memory url = concat4(COINGECKO_BASE_URL, base, PRECISION_QUERY_URL, asset); + string[] memory command = new string[](2); + command[0] = "curl"; + command[1] = url; + + string memory response = string(vm.ffi(command)); + emit log_named_string("response", response); + string memory jqFilter = concat4(".", asset, ".", base); + string memory floatPointPrice = string(vm.parseJsonString(response, jqFilter)); + return floatPointToUint(floatPointPrice); + } + + function concat4( + string memory str0, + string memory str1, + string memory str2, + string memory str3 + ) internal returns (string memory) { + return string(bytes.concat(bytes.concat(bytes(str0), bytes(str1)), bytes.concat(bytes(str2), bytes(str3)))); + } + + function floatPointToUint(string memory str) internal returns (uint256) { + bytes memory asBytes = bytes(str); + uint256 k; + + for (uint256 i = 0; i < asBytes.length; i++) { + if (asBytes[i] != ".") k++; + } + + bytes memory noPointBytes = new bytes(k); + k = 0; + for (uint256 i = 0; i < asBytes.length; i++) { + if (asBytes[i] != ".") noPointBytes[k++] = asBytes[i]; + } + + return vm.parseUint(string(noPointBytes)); + } +} diff --git a/lib/forge-std b/lib/forge-std index 2a2ce3692..c2236853a 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 2a2ce3692b8c1523b29de3ec9d961ee9fbbc43a6 +Subproject commit c2236853aadb8e2d9909bbecdc490099519b70a4