Platform: Code4rena
Start Date: 27/04/2022
Pot Size: $50,000 MIM
Total HM: 6
Participants: 59
Period: 5 days
Judge: 0xean
Id: 113
League: ETH
Rank: 27/59
Findings: 2
Award: $139.50
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1337, 0x1f8b, 0xDjango, 0xf15ers, AuditsAreUS, BowTiedWardens, CertoraInc, Funen, GimelSec, MaratCerby, Ruhum, WatchPug, antonttc, berndartmueller, bobi, bobirichman, broccolirob, catchup, cccz, defsec, delfin454000, gs8nrv, gzeon, horsefacts, hubble, hyh, ilan, jah, joestakey, kebabsec, kenta, kenzo, m9800, mics, oyc_109, pauliax, reassor, robee, samruna, sikorico, simon135, throttle, unforgiven, z3s
95.0451 MIM - $95.05
uint8 private constant LOAN_INITIAL = 0; uint8 private constant LOAN_REQUESTED = 1; uint8 private constant LOAN_OUTSTANDING = 2;
uint256 private constant YEAR_BPS = 3600 * 24 * 365 * 10_000; uint256 private constant YEAR_BPS = 365 days;
I think all the functions that validate signatures, should also include DOMAIN_SEPARATOR(). Now this function is basically unused, and in the theoretical case if contract addresses are identical on different chains, the signature replay attack can be executed.
Signature validations should check that ecrecover does not return an empty address (0x0) which is the case when the signature is invalid.
Unprotected function init can be frontrunned by anyone. Even though the risk is small, consider applying onlyOwner to it.
Function cook could validate that all the lengths of actions, values, and datas are the equal.
Consider adding a re-entrancy protection or follow the Check-Effects-Interaction pattern to avoid unexpeced re-entrancy attacks even if you trust the callee, e.g. the order of lines should be swapped here:
bentoBox.transfer(asset, address(this), to, _share); feesEarnedShare = 0;
also everywhere where NFT collateral or other tokens are transferred it should happend as the final action, e.g. function _requestLoan.
#0 - cryptolyndon
2022-05-13T05:39:17Z
Seen, thanks
Suggested change for YEAR_BPS misses a factor 10000
It's a few levels deep, but the domain separator is in fact used
If #1 and #3 are legitimate issues, then so is this (ecrecover)
🌟 Selected for report: BowTiedWardens
Also found by: 0x1f8b, 0xNazgul, 0xf15ers, 0xkatana, CertoraInc, Funen, GimelSec, Hawkeye, IllIllI, Kulk0, NoamYakov, Tadashi, Tomio, TrungOre, antonttc, catchup, defsec, delfin454000, fatherOfBlocks, gzeon, horsefacts, joestakey, kenta, oyc_109, pauliax, reassor, robee, samruna, simon135, slywaters, sorrynotsorry, z3s
44.4477 MIM - $44.45
function withdrawFees() public { address to = masterContract.feeTo();
There is a variable named feeTo which is supposed to receive fees, so it should probably be cheapier to directly read it.
bentoBox.balanceOf(asset, address(this)) >= (totalShare - openFeeShare + protocolFeeShare + feesEarnedShare) bentoBox.transfer(asset, lender, address(this), totalShare - openFeeShare + protocolFeeShare); uint256 borrowerShare = totalShare - openFeeShare;
uint8[] calldata actions, uint8 internal constant ACTION_REPAY = 2; uint8 internal constant ACTION_REMOVE_COLLATERAL = 4; uint8 internal constant ACTION_REQUEST_LOAN = 12; uint8 internal constant ACTION_LEND = 13; // Function on BentoBox uint8 internal constant ACTION_BENTO_DEPOSIT = 20; uint8 internal constant ACTION_BENTO_WITHDRAW = 21; uint8 internal constant ACTION_BENTO_TRANSFER = 22; uint8 internal constant ACTION_BENTO_TRANSFER_MULTIPLE = 23; uint8 internal constant ACTION_BENTO_SETAPPROVAL = 24; // Any external call (except to BentoBox) uint8 internal constant ACTION_CALL = 30; // Signed requests uint8 internal constant ACTION_REQUEST_AND_BORROW = 40; uint8 internal constant ACTION_TAKE_COLLATERAL_AND_LEND = 41;
using RebaseLibrary for Rebase;
#0 - cryptolyndon
2022-05-13T06:09:41Z
Seen, thanks.