Platform: Code4rena
Start Date: 08/05/2023
Pot Size: $90,500 USDC
Total HM: 17
Participants: 102
Period: 7 days
Judge: 0xean
Total Solo HM: 4
Id: 236
League: ETH
Rank: 66/102
Findings: 1
Award: $56.63
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: brgltd
Also found by: 0x73696d616f, 0xAce, 0xSmartContract, 0xWaitress, 0xkazim, 0xnev, Aymen0909, BGSecurity, Bauchibred, Cayo, ChrisTina, Franfran, IceBear, Infect3d, Kose, Lilyjjo, PNS, RaymondFam, Sathish9098, Team_Rocket, Udsen, YakuzaKiawe, YoungWolves, berlin-101, bin2chen, btk, codeslide, fatherOfBlocks, frazerch, kodyvim, koxuan, lfzkoala, lukris02, matrix_0wl, nadin, naman1778, sashik_eth, tnevler, volodya, wonjun, yjrwkk
56.6347 USDC - $56.63
During the audit, 1 low and 8 non-critical issues were found.
â„– | Title | Risk Rating | Instance Count |
---|---|---|---|
L-1 | Add a timelock to critical functions | Low | 20 |
NC-1 | Update import usages | Non-Critical | 1 |
NC-2 | Scientific notation may be used | Non-Critical | 2 |
NC-3 | Unused event | Non-Critical | 1 |
NC-4 | If possible, place if/require-statements at the top of the function | Non-Critical | 1 |
NC-5 | Prevent zero transfers | Non-Critical | 4 |
NC-6 | Lack of event emission in initialize() function | Non-Critical | 7 |
NC-7 | No same value input control | Non-Critical | 14 |
NC-8 | Missing leading underscores | Non-Critical | 64 |
Giving users time to react and adjust to critical changes in protocol provides more guarantees and increases the transparency of the protocol.
function setCloseFactor(uint256 newCloseFactorMantissa) external {
function setCollateralFactor(
function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {
function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {
function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {
function setPriceOracle(PriceOracle newOracle) external onlyOwner {
function setMaxLoopsLimit(uint256 limit) external onlyOwner {
function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {
function setInterestRateModel(InterestRateModel newInterestRateModel) external override {
function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {
function setShortfallContract(address shortfall_) external onlyOwner {
function setMaxLoopsLimit(uint256 limit) external onlyOwner {
function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {
function setShortfallContract(Shortfall shortfall_) external onlyOwner {
function setPoolRegistry(address _poolRegistry) external onlyOwner {
function setShortfallContractAddress(address shortfallContractAddress_) external onlyOwner {
function setPancakeSwapRouter(address pancakeSwapRouter_) external onlyOwner {
function setMinAmountToConvert(uint256 minAmountToConvert_) external {
function setMaxLoopsLimit(uint256 limit) external onlyOwner {
function setPoolRegistry(address _poolRegistry) external onlyOwner {
Consider adding a timelock.
For modern and more readable code, consider updating import usages.
Change to:
import {contract1 , contract2} from "filename.sol";
For readability and to avoid misprints, it is better to use scientific notation.
Replace 10000
with 10e4
.
The event AmountOutMinUpdated
is not emitted.
Emit event or delete it.
Validation of input parameters should be at the beginning of the function.
Check that amount to transfer > 0.
token.safeTransferFrom(from, address(this), amount);
token.safeTransfer(to, amount);
token.safeTransferFrom(from, address(this), amount);
IERC20Upgradeable(convertibleBaseAsset).safeTransfer(shortfall, amount);
Lack of event emission complicates recording the init parameters for off-chain monitoring and reduces transparency.
Consider emitting an event in the initialize() function
function setCloseFactor(uint256 newCloseFactorMantissa) external {
function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {
function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {
function setPriceOracle(PriceOracle newOracle) external onlyOwner {
function _setComptroller(ComptrollerInterface newComptroller) internal {
function _setShortfallContract(address shortfall_) internal {
function _setProtocolShareReserve(address payable protocolShareReserve_) internal {
function _setShortfallContract(Shortfall shortfall_) internal {
function _setProtocolShareReserve(address payable protocolShareReserve_) internal {
function setPoolRegistry(address _poolRegistry) external onlyOwner {
function setPancakeSwapRouter(address pancakeSwapRouter_) external onlyOwner {
function setMinAmountToConvert(uint256 minAmountToConvert_) external {
function setPoolRegistry(address _poolRegistry) external onlyOwner {
function _setMaxLoopsLimit(uint256 limit) internal {
Check if (variableA == parameterA) revert SameValue();
Internal and private state variables, constants, immutables and functions should have a leading underscore.
function updateMarketBorrowIndex(
function updateMarketSupplyIndex(
function calculateBorrowerReward(
function calculateSupplierReward(
IRiskFund private riskFund;
uint256 private incentiveBps;
uint256 private constant MAX_BPS = 10000;
Comptroller private comptroller;
address private pancakeSwapRouter;
uint256 private minAmountToConvert;
address private convertibleBaseAsset;
address private shortfall;
uint256 internal constant borrowRateMaxMantissa = 0.0005e16;
uint256 internal constant reserveFactorMaxMantissa = 1e18;
uint256 internal initialExchangeRateMantissa;
mapping(address => uint256) internal accountTokens;
mapping(address => mapping(address => uint256)) internal transferAllowances;
mapping(address => BorrowSnapshot) internal accountBorrows;
uint256 internal constant expScale = 1e18;
uint256 internal constant doubleScale = 1e36;
uint256 internal constant halfExpScale = expScale / 2;
uint256 internal constant mantissaOne = expScale;
function truncate(Exp memory exp) internal pure returns (uint256) {
function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {
function mul_ScalarTruncateAddUInt(
function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {
function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {
function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {
function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {
function add_(Double memory a, Double memory b) internal pure returns (Double memory) {
function add_(uint256 a, uint256 b) internal pure returns (uint256) {
function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {
function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {
function sub_(uint256 a, uint256 b) internal pure returns (uint256) {
function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {
function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {
function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {
function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {
function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {
function mul_(uint256 a, Double memory b) internal pure returns (uint256) {
function mul_(uint256 a, uint256 b) internal pure returns (uint256) {
function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {
function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {
function div_(uint256 a, Exp memory b) internal pure returns (uint256) {
function div_(Double memory a, Double memory b) internal pure returns (Double memory) {
function div_(Double memory a, uint256 b) internal pure returns (Double memory) {
function div_(uint256 a, Double memory b) internal pure returns (uint256) {
function div_(uint256 a, uint256 b) internal pure returns (uint256) {
function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {
uint256 private constant BASE = 1e18;
RewardsDistributor[] internal rewardsDistributors;
mapping(address => bool) internal rewardsDistributorExists;
uint256 internal constant NO_ERROR = 0;
uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05
uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9
uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9
address private protocolIncome;
address private riskFund;
uint256 private constant protocolSharePercentage = 70;
uint256 private constant baseUnit = 100;
uint256 private constant BASE = 1e18;
mapping(address => uint256) internal assetsReserves;
mapping(address => mapping(address => uint256)) internal poolsAssetsReserves;
address internal poolRegistry;
Add leading underscores where needed.
#0 - c4-judge
2023-05-18T18:34:08Z
0xean marked the issue as grade-b