We continue our series of instructive articles with some special recommendations for developers using Compound v2 DeFi integration!
We understand and respect your limited time, therefore we created a specific article with nothing superfluous for an easier access! 🙂
In this article, we present tips that we have acquired over the years of auditing such integrations.
By the way, here are some vacant slots so if your project needs an audit — feel free to write to us, visit our public reports page here!
We chose to conduct a thorough analysis of Compound v2 because it is the version of the protocol that integrations use the most frequently, as evidenced by its TVL.
We hope to inform you of the checks pertaining to Compound III integration in the upcoming articles as well!
Following the tips below can significantly improve the security of your project’s integration, so you should always keep them in mind!
There are two types of cToken: cErc20 and cEther (for native Ether). Some functions may have different arguments! For example, for mint function: A) In cEther, amount is passed in msg.value; B) In cErc20 amount is passed in the parameter mintAmount.
For cToken, decimals equals 8 — all cTokens have 8 decimals, while the underlying token can vary. It is worth to keep this in mind when performing calculations!
Some functions return mantissa (scaled by 1e18
), for example: suppyRatePerBlock
, you should always check how the function returns the value;
In order to calculate the cTokenRate, perform the following:
exchangeRateCurrent = cToken.exchangeRateCurrent() // it is returned as mantissa (scaled by 1e18)
oneCTokenInUnderlying = exchangeRateCurrent / (1 * 10 ^ (18 + underlyingDecimals - cTokenDecimals) // we divide by 1e18 + decimal difference
Not every token can be used as a collateral. For some tokens collaterallFactor
(you can get it from the comptroller) may be equal to zero. Also, keep in mind that compound admin has the ability to change the collaterallFactor
of any token;
Compound functions may return errorCode
(uint type, 0
→ NO_ERROR
). In previous versions, the transaction did not revert, but in the updated v2, it reverts or returns NO_ERROR
. But you should always make sure that Compound functions will not fail without reverting;
The cToken
can be transferred, but the protocol will not let this happen if after the transfer the accountLiqudity < 0
(the user does not have enough collateral to cover all the loans);
When supplying tokens, you have to check if there is an approve given;
The number of underLying
tokens per сToken
may increase over time! Each cToken will increase its value on a (almost) per block basis due to the interests earned. You can use the cToken as collateral to borrow funds. You can also use it in other markets (it is an ERC20 compatible token).
TUSD, USDC, USDT — are hardcoded as $1;
Compound uses chainlink as a price feed, it also verifies data via a TWAP oracle from the Uniswap;
Users are rewarded with COMP tokens for interaction with the protocol. You should always make sure that the contract that works with Compound has a built-in functionality that allows these tokens to be claimed.
Carefully study the Comptroller, you can find it here. The Comptroller is architected as an upgradable proxy, the name of the actual proxy is named the “Unitroller”, you can find the contract’s code here.
There are 2 types of cTokens : cErc20, cEther. (cEther wraps native Ether token);
Interfaces for cToken and cEther (contract) may differ. For example, in mint function;
You can earn interest over time, by holding cToken. Amount of cToken remains the same, but exchange rate to underlying token will change;
When a market is launched, the cToken exchange rate (how much ETH one cETH is worth) begins at 0.020000. Each user has the same cToken exchange rate;
cTokens are transferable;
The cETH token contract has no underlying() getter. It’s important to note as this what lead to the failing upgrade of the Compound oracle last time. (Much thanks, Merlin!). Things to double-check before integrating Morpho-CompoundV2;
A cToken transfer will fail if the account has entered that cToken market and the transfer would have put the account into a state of negative liquidity;
Price for borrows and collaterals are calculated in Ether;
If accountLiqudity = sumCollateral-sumBorrow , it should be >= 0 , otherwise the account health factor drops below zero;
Most functions trigger accrueInterest
which in turn recalculates pool index rate;
Support is very important to me, with it I can do what I love — educating users!
If you want to support my work, you can send me a donation to the address:
0xB25C5E8fA1E53eEb9bE3421C59F6A66B786ED77A or officercia.eth — ETH, BSC, Polygon, Optimism, Zk, Fantom, etc
4AhpUrDtfVSWZMJcRMJkZoPwDSdVG6puYBE3ajQABQo6T533cVvx5vJRc5fX7sktJe67mXu1CcDmr7orn1CrGrqsT3ptfds — Monero XMR