Compound Protocol Adapter
The Compound adapter enables the Yieldinator Facet to integrate with Compound's money markets, allowing vaults to earn yield by supplying assets to Compound's lending protocol.
Overview
Compound is a decentralized lending protocol that allows users to supply assets to earn interest and borrow assets against collateral. The Compound adapter facilitates deposits into Compound markets, manages cToken balances, and harvests yield generated from lending interest and COMP token rewards.
Implementation Details
Contract: CompoundAdapter.sol
CompoundAdapter.solThe adapter implements the standard YieldinatorAdapter interface with Compound-specific functionality:
contract CompoundAdapter is YieldinatorAdapter {
// Compound contracts
IComptroller public comptroller;
address public compToken;
// Mapping from underlying asset to cToken
mapping(address => address) public assetToCToken;
// Deposited amounts per token
mapping(address => uint256) public depositedAmount;
// Constructor and core functions...
}Key Functions
Asset Registration
Before using the adapter for a specific token, the asset must be registered with its corresponding cToken:
function registerAsset(address _asset, address _cToken) external onlyRole(ADAPTER_ADMIN_ROLE)Deposit
Deposits tokens into Compound's money markets:
function deposit(address _token, uint256 _amount) external override onlyRole(YIELDINATOR_ROLE) nonReentrant returns (bool)The function:
Transfers tokens from the caller to the adapter
Approves the cToken contract to spend the tokens
Mints cTokens by supplying the underlying asset
Updates the deposited amount tracking
Withdraw
Withdraws tokens from Compound's money markets:
function withdraw(address _token, uint256 _amount) external override onlyRole(YIELDINATOR_ROLE) nonReentrant returns (bool)Harvest Yield
Harvests accrued interest and COMP rewards:
function harvestYield(address _token) external override onlyRole(YIELDINATOR_ROLE) nonReentrant returns (uint256)The function:
Calculates yield based on the exchange rate between cTokens and the underlying asset
Redeems only the yield portion, leaving the principal intact
Claims COMP token rewards from the Comptroller
Transfers both the yield and COMP rewards to the caller
Emergency Withdraw
Provides emergency withdrawal functionality:
function emergencyWithdraw(address _token) external override onlyRole(YIELDINATOR_ROLE) nonReentrant returns (uint256)APY Calculation
Returns the current APY for a token in Compound:
function getCurrentAPY(address _token) external view override returns (uint256)The APY is calculated based on Compound's supplyRatePerBlock, converted to an annual percentage with 2 decimal places (scaled by 10000).
Additional Functions
The adapter includes additional Compound-specific functions:
function getCToken(address _asset) external view returns (address)
function getAccruedComp() external view returns (uint256)Usage Example
// Initialize the adapter
CompoundAdapter compoundAdapter = new CompoundAdapter(comptrollerAddress, compTokenAddress, adminAddress);
// Register an asset
compoundAdapter.registerAsset(daiAddress, cDaiAddress);
// Deposit tokens
compoundAdapter.deposit(daiAddress, 1000 * 1e18);
// After some time, harvest yield
uint256 harvestedYield = compoundAdapter.harvestYield(daiAddress);
// Withdraw tokens
compoundAdapter.withdraw(daiAddress, 500 * 1e18);
// In case of emergency
compoundAdapter.emergencyWithdraw(daiAddress);
// Check accrued COMP rewards
uint256 pendingComp = compoundAdapter.getAccruedComp();Security Considerations
The adapter uses OpenZeppelin's SafeERC20 for token transfers to prevent common ERC20 vulnerabilities.
Non-reentrancy guards protect against reentrancy attacks during external calls.
Role-based access control ensures only authorized addresses can call sensitive functions.
The adapter checks Compound operation result codes to ensure successful execution.
Gas Optimization
The adapter minimizes the number of external calls to Compound contracts.
Token approvals are set exactly to the amount being deposited to avoid unnecessary approvals.
COMP rewards are claimed in the same transaction as yield harvesting to save gas.
Integration Requirements
To use the Compound adapter, the following components are required:
A Compound Comptroller address for the target network
The COMP token address
The corresponding cToken addresses for each asset
Proper role assignments for the Yieldinator Facet