Platform: Code4rena
Start Date: 28/09/2023
Pot Size: $36,500 USDC
Total HM: 5
Participants: 115
Period: 6 days
Judge: 0xDjango
Total Solo HM: 1
Id: 290
League: ETH
Rank: 90/115
Findings: 1
Award: $4.37
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Bauchibred
Also found by: 0x3b, 0xDetermination, 0xMosh, 0xScourgedev, 0xTheC0der, 0xTiwa, 0xWaitress, 0xdice91, 0xfusion, 0xpiken, 0xprinc, 0xweb3boy, ArmedGoose, Aymen0909, Breeje, Brenzee, Daniel526, DavidGiladi, DeFiHackLabs, Flora, Fulum, HChang26, Hama, IceBear, J4X, Krace, KrisApostolov, Maroutis, Mirror, MohammedRizwan, Norah, PwnStars, SPYBOY, TangYuanShen, Testerbot, ThreeSigma, Tricko, al88nsk, alexweb3, ast3ros, berlin-101, bin2chen, blutorque, btk, d3e4, deth, e0d1n, ether_sky, ge6a, gkrastenov, glcanvas, hals, imare, inzinko, jkoppel, jnforja, joaovwfreire, josephdara, kutugu, lotux, lsaudit, mahdirostami, merlin, n1punp, nadin, neumo, nisedo, nobody2018, oakcobalt, orion, peanuts, pep7siup, pina, ptsanev, rokinot, rvierdiiev, said, santipu_, sashik_eth, seerether, squeaky_cactus, terrancrypt, tonisives, twicek, vagrant, xAriextz, y4y
4.3669 USDC - $4.37
ID | Title |
---|---|
L-01 | Missing check for market existence before APR calculation |
L-02 | Shadowing named return variable declaration |
L-03 | Excessive rights for claimInterest() |
L-04 | The calculation of userYearlyIncome uses the number of blocks mined annually |
L-05 | Incomplete configuration of _setMaxLoopsLimit() |
N-01 | Incorrect comments |
N-02 | Incorrect gap size |
N-03 | Typos |
An explicit check for market
existence could be added to the calculateAPR()
and estimateAPR()
functions, so that when a user inputs an unsupported market, the function will throw appropriate error messages.
function calculateAPR(address market, address user) external view returns (uint256 supplyAPR, uint256 borrowAPR) { IVToken vToken = IVToken(market);
function estimateAPR( ... ) external view returns (uint256 supplyAPR, uint256 borrowAPR) { uint256 totalScore = markets[market].sumOfMembersScore - interests[market][user].score;
1 instance
function getPendingInterests(address user) external returns (PendingInterest[] memory pendingInterests) { address[] storage _allMarkets = allMarkets; - PendingInterest[] memory pendingInterests = new PendingInterest[](_allMarkets.length); + pendingInterests = new PendingInterest[](_allMarkets.length);
Function claimInterest()
in Prime.sol
allows anyone to claim any user's interest.
function claimInterest(address vToken, address user) external whenNotPaused returns (uint256) { return _claimInterest(vToken, user); }
In some cases, user do not want to receive funds right now (leak of keys and being in process in negotiation with validators etc.)
userYearlyIncome
uses the number of blocks mined annuallyThe calculation of userYearlyIncome uses the number of blocks mined annually. The code will be deployed on BNB Chain, Ethereum mainnet, Arbitrum, Polygon zkEVM and opBNB. It'll be fine for BNB Chain and Ethereum mainnet, which have a fixed block produce time. However, on Arbitrum, Polygon zkEVM and opBNB, BLOCKS_PER_YEAR is an estimated value.
Unavailable to add enough markets if maxLoopsLimit
of MaxLoopsLimitHelper()
is set too small, and there's no external function to update maxLoopsLimit
.
Abstract contract MaxLoopsLimitHelper
is used to control length of array in contracts. This limit is setting during initialize of SC's. There is loose requirement which control this length exactly at init process (0 by default).
require(limit > maxLoopsLimit, "Comptroller: Invalid maxLoopsLimit");
According to the document and implementation, _executeBoost
is called by Comptroller after changing account's borrow or supply balance, while it's stated before in the comment.
In Comptroller (specifically in the
PolicyFacet
), after executing any operation that could impact the Prime score or interest, we accrue the interest and update the score for the Prime user by callingaccrueInterestAndUpdateScore
.
/** * @notice Accrue rewards for the user. Must be called by Comptroller before changing account's borrow or supply balance. * @param user account for which we need to accrue rewards * @param vToken the market for which we need to accrue rewards */ function _executeBoost(address user, address vToken) internal {
In the PrimeStorageV1 contract, the number of used storage slots is 24, while the gap size is 25.
2 instances
interes should be interest.
* @notice accrues interes and updates score for an user for a specific market
intialized should be initialized.
PrimeLiquidityProvider.sol#115
* @param tokens_ Array of addresses of the tokens to be intialized
#0 - c4-pre-sort
2023-10-07T03:08:48Z
0xRobocop marked the issue as low quality report