// SPDX-License-Identifier: BlueOak-1.0.0
pragma solidity 0.8.17;
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "../../../libraries/Fixed.sol";
import "../AppreciatingFiatCollateral.sol";
import "./ICToken.sol";
/**
* @title CTokenFiatCollateral
* @notice Collateral plugin for a cToken of fiat collateral, like cUSDC or cUSDP
* Expected: {tok} != {ref}, {ref} is pegged to {target} unless defaulting, {target} == {UoA}
* Also used for FluxFinance
*/
contract CTokenFiatCollateral is AppreciatingFiatCollateral {
using OracleLib for AggregatorV3Interface;
using FixLib for uint192;
// All v2 cTokens have 8 decimals, but their underlying may have 18 or 6 or something else.
uint8 public immutable referenceERC20Decimals;
IComptroller public immutable comptroller;
/// @param revenueHiding {1} A value like 1e-6 that represents the maximum refPerTok to hide
/// @param comptroller_ The CompoundFinance Comptroller
constructor(
CollateralConfig memory config,
uint192 revenueHiding,
IComptroller comptroller_
) AppreciatingFiatCollateral(config, revenueHiding) {
require(address(comptroller_) != address(0), "comptroller missing");
ICToken erc20 = ICToken(address(config.erc20));
referenceERC20Decimals = IERC20Metadata(erc20.underlying()).decimals();
comptroller = comptroller_;
}
/// Refresh exchange rates and update default status.
/// @custom:interaction RCEI
function refresh() public virtual override {
// == Refresh ==
// Update the Compound Protocol
ICToken(address(erc20)).exchangeRateCurrent();
// Intentional and correct for the super call to be last!
super.refresh(); // already handles all necessary default checks
}
/// @return {ref/tok} Actual quantity of whole reference units per whole collateral tokens
function _underlyingRefPerTok() internal view override returns (uint192) {
uint256 rate = ICToken(address(erc20)).exchangeRateStored();
int8 shiftLeft = 8 - int8(referenceERC20Decimals) - 18;
return shiftl_toFix(rate, shiftLeft);
}
/// Claim rewards earned by holding a balance of the ERC20 token
/// @dev delegatecall
function claimRewards() external virtual override(Asset, IRewardable) {
IERC20 comp = IERC20(comptroller.getCompAddress());
uint256 oldBal = comp.balanceOf(address(this));
comptroller.claimComp(address(this));
emit RewardsClaimed(comp, comp.balanceOf(address(this)) - oldBal);
}
}
|