Skip to content

Commit

Permalink
Merge branch 'beanstalk3-codehawks-remediations' of https://github.co…
Browse files Browse the repository at this point in the history
  • Loading branch information
funderbrker committed Aug 20, 2024
2 parents 222f952 + 115a53e commit da4639a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 24 deletions.
11 changes: 10 additions & 1 deletion protocol/contracts/libraries/Oracle/LibUsdOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,16 @@ library LibUsdOracle {
0,
lookback
);
return tokenPrice.mul(chainlinkTokenPrice).div(CHAINLINK_DENOMINATOR);

// if token decimals != 0, Beanstalk is attempting to query the USD/TOKEN price, and
// thus the price needs to be inverted.
if (tokenDecimals != 0) {
tokenPrice = (10 ** (6 + tokenDecimals)) / tokenPrice;
return (tokenPrice * chainlinkTokenPrice) / (10 ** tokenDecimals);
} else {
// return the TOKEN/USD price.
return (tokenPrice * chainlinkTokenPrice) / CHAINLINK_DENOMINATOR;
}
}

// If the oracle implementation address is not set, use the current contract.
Expand Down
71 changes: 48 additions & 23 deletions protocol/test/foundry/silo/Oracle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,7 @@ contract OracleTest is TestHelper {
uint256 price = OracleFacet(address(bs)).getUsdTokenPrice(WBTC);
assertEq(price, 0.00002e8, "price using encode type 0x01");

// change encode type to 0x02:
vm.prank(address(bs));
bs.updateOracleImplementationForToken(
WBTC,
IMockFBeanstalk.Implementation(
WBTC_USDC_03_POOL,
bytes4(0),
bytes1(0x02),
abi.encode(LibChainlinkOracle.FOUR_HOUR_TIMEOUT)
)
);

// also uniswap relies on having a chainlink oracle for the dollar-denominated token, in this case USDC
vm.prank(address(bs));
bs.updateOracleImplementationForToken(
C.USDC,
IMockFBeanstalk.Implementation(
USDC_USD_CHAINLINK_PRICE_AGGREGATOR,
bytes4(0),
bytes1(0x01),
abi.encode(LibChainlinkOracle.FOUR_DAY_TIMEOUT)
)
);
setupUniswapWBTCOracleImplementation();

price = OracleFacet(address(bs)).getTokenUsdPrice(WBTC);
// 1 USDC will get ~500 satoshis of BTC at $50k
Expand All @@ -66,6 +44,28 @@ contract OracleTest is TestHelper {
assertApproxEqRel(price, 50000e6, 0.001e18, "price using encode type 0x02");
}

function test_uniswap_external() public {
setupUniswapWBTCOracleImplementation();

// exercise TokenUsd price and UsdToken price
uint256 tokenUsdPriceFromExternal = OracleFacet(BEANSTALK).getTokenUsdPriceFromExternal(
WBTC,
0
);
assertApproxEqRel(
tokenUsdPriceFromExternal,
50000e6,
0.001e18,
"tokenUsdPriceFromExternal"
);

uint256 usdTokenPriceFromExternal = OracleFacet(BEANSTALK).getUsdTokenPriceFromExternal(
WBTC,
0
);
assertEq(usdTokenPriceFromExternal, 0.00002e6, "usdTokenPriceFromExternal");
}

/**
* @notice verifies functionality with LSDChainlinkOracle.sol.
*/
Expand Down Expand Up @@ -282,4 +282,29 @@ contract OracleTest is TestHelper {
uint256 priceWBTC = OracleFacet(address(bs)).getUsdTokenPrice(WBTC);
assertEq(priceWBTC, 0.00002e8); // adjusted to 8 decimals
}

function setupUniswapWBTCOracleImplementation() public {
vm.prank(address(bs));
bs.updateOracleImplementationForToken(
WBTC,
IMockFBeanstalk.Implementation(
WBTC_USDC_03_POOL,
bytes4(0),
bytes1(0x02),
abi.encode(LibChainlinkOracle.FOUR_HOUR_TIMEOUT)
)
);

// also uniswap relies on having a chainlink oracle for the dollar-denominated token, in this case USDC
vm.prank(address(bs));
bs.updateOracleImplementationForToken(
C.USDC,
IMockFBeanstalk.Implementation(
USDC_USD_CHAINLINK_PRICE_AGGREGATOR,
bytes4(0),
bytes1(0x01),
abi.encode(LibChainlinkOracle.FOUR_DAY_TIMEOUT)
)
);
}
}

0 comments on commit da4639a

Please sign in to comment.