Platform: Code4rena
Start Date: 14/06/2022
Pot Size: $100,000 USDC
Total HM: 26
Participants: 59
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 9
Id: 133
League: ETH
Rank: 5/59
Findings: 8
Award: $4,445.77
🌟 Selected for report: 0
🚀 Solo Findings: 0
1987.1989 CANTO - $320.93
320.9326 USDC - $320.93
The hardcoded return value is the address of COMP
token in mainnet not of WETH
in getWETHAddress()
.
https://etherscan.io/address/0xc00e94Cb662C3520282E6f5717214004A7f26888
grantCompInternal()
function depends on this return value which will cause unintended issues.
function grantCompInternal(address user, uint amount) internal returns (uint) { WETH comp = WETH(payable(getWETHAddress())); // called here uint compRemaining = comp.balanceOf(address(this)); if (amount > 0 && amount <= compRemaining) { comp.transfer(user, amount); return 0; } return amount; } function getWETHAddress() virtual public view returns (address) { return 0xc00e94Cb662C3520282E6f5717214004A7f26888; }
#0 - ecmendenhall
2022-06-21T21:55:14Z
#1 - nivasan1
2022-06-21T22:17:33Z
duplicate of issue #242
🌟 Selected for report: hansfriese
Also found by: 0xf15ers
1467.456 USDC - $1,467.46
9086.4148 CANTO - $1,467.46
Judge has assessed an item in Issue #210 as High risk. The relevant finding follows:
#0 - GalloDaSballo
2022-08-13T00:09:46Z
Dup of #218
#1 - GalloDaSballo
2022-08-13T00:09:59Z
function allowance(address owner, address spender) external view returns (uint256) { return _allowance[owner][spender]; }
🌟 Selected for report: csanuragjain
1635.5547 CANTO - $264.14
264.1421 USDC - $264.14
repayAmountFinal
is not used inside repayBorrowFresh()
actualRepayAmount
doesnot account for repayAmountFinal
in L111.function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal override returns(uint){ ................. uint repayAmountFinal = repayAmount == type(uint).max ? accountBorrowsPrev : repayAmount; //this cannot be a require statement, it must be accounted for if this is the case require(getCashPrior() == 0, "CNote::repayBorrowFresh:Liquidity in Note Lending Market is always flashed"); //make sure that this is remedied ................... uint actualRepayAmount = doTransferIn(payer, repayAmount); .......... }
Manual analysis
Use uint actualRepayAmount = doTransferIn(payer, repayAmountFinal);
#0 - tkkwon1998
2022-06-22T19:52:04Z
Duplicate of #98
#1 - GalloDaSballo
2022-08-10T23:55:49Z
Dup of #98
🌟 Selected for report: joestakey
Also found by: 0x1f8b, 0x29A, 0x52, 0xDjango, 0xNazgul, 0xf15ers, 0xmint, Bronicle, Dravee, Funen, JMukesh, Limbooo, MadWookie, Picodes, Ruhum, TerrierLover, TomJ, Tutturu, WatchPug, Waze, _Adam, asutorufos, c3phas, catchup, cccz, codexploder, cryptphi, csanuragjain, defsec, fatherOfBlocks, gzeon, hake, hansfriese, hyh, ignacio, k, nxrblsrpr, oyc_109, robee, sach1r0, saian, simon135, technicallyty, zzzitron
687.9945 CANTO - $111.11
124.2387 USDC - $124.24
uint cash, uint borrows, uint reserves
are not used inside the function.uint reserveFactorMantissa
parameter is unsused.OnlyUniGov
is not used anywher inside the contract Proposal-Store.sol
Proposal-Store.sol
redeemVerify()'s
visibility can be changed to pure
view
require()
deposit()
and withdraw()
allowance(address owner, address spender)
in WETH.sol
returns 0
alwaysreturn
// recommendation function allowance(address owner, address spender) external view returns (uint256) { return _allowance[owner][spender]; }
#0 - GalloDaSballo
2022-08-01T23:11:39Z
Valid NC
Valid Refactoring
Valid NC
Valid Ref
Valid NC
Valid NC
Valid Low
TODO -> Bump Allowance
Neat report, great format
1L 2R 4NC
🌟 Selected for report: _Adam
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 0xmint, Chom, Dravee, Fitraldys, Funen, JC, Limbooo, MadWookie, Picodes, Ruhum, TerrierLover, TomJ, Tomio, Waze, ak1, c3phas, catchup, defsec, fatherOfBlocks, gzeon, hake, hansfriese, joestakey, k, oyc_109, rfa, robee, sach1r0, saian, simon135, ynnad
41.2642 USDC - $41.26
396.9199 CANTO - $64.10
address(0)
in Note.sol#L6 for eg.
uint256 len = assets.length; for(uint256 i = 0; i < len; i++) { ... }
> grep -rn '.' -e 'for.*[.]length' ./Comptroller.sol:736: for (uint i = 0; i < assets.length; i++) { ./Comptroller.sol:960: for (uint i = 0; i < allMarkets.length; i ++) { ./Comptroller.sol:1107: for (uint i = 0; i < affectedUsers.length; ++i) { ./Comptroller.sol:1348: for (uint i = 0; i < cTokens.length; i++) { ./Comptroller.sol:1354: for (uint j = 0; j < holders.length; j++) { ./Comptroller.sol:1360: for (uint j = 0; j < holders.length; j++) { ./Comptroller.sol:1365: for (uint j = 0; j < holders.length; j++) { ./ComptrollerG7.sol:719: for (uint i = 0; i < assets.length; i++) { ./ComptrollerG7.sol:942: for (uint i = 0; i < allMarkets.length; i ++) { ./ComptrollerG7.sol:1233: for (uint i = 0; i < cTokens.length; i++) { ./ComptrollerG7.sol:1239: for (uint j = 0; j < holders.length; j++) { ./ComptrollerG7.sol:1246: for (uint j = 0; j < holders.length; j++) { ./Lens/CompoundLens.sol:343: for (uint i = 0; i < proposalIds.length; i++) { ./Lens/CompoundLens.sol:404: for (uint i = 0; i < proposalIds.length; i++) {
++i
) is cheaper than postfix increment (i++
)Using prefix increment saves small amount of gas than postfix increment because it returns the updated value hence doesn't requires to store intermediate value. This can be more significant in loops where this operation is done multiple times.
for eg.
// before for(uint256 i = 0; i < len; i++) { ... } // Replace with for(uint256 i = 0; i < len; ++i) { ... }
./Comptroller.sol:206: for (uint i = 0; i < len; i++) { ./Comptroller.sol:736: for (uint i = 0; i < assets.length; i++) { ./Comptroller.sol:1006: for(uint i = 0; i < numMarkets; i++) { ./Comptroller.sol:1348: for (uint i = 0; i < cTokens.length; i++) { ./ComptrollerG7.sol:116: for (uint i = 0; i < len; i++) { ./ComptrollerG7.sol:196: for (uint i = 0; i < len; i++) { ./ComptrollerG7.sol:719: for (uint i = 0; i < assets.length; i++) { ./ComptrollerG7.sol:963: for(uint i = 0; i < numMarkets; i++) { ./ComptrollerG7.sol:1233: for (uint i = 0; i < cTokens.length; i++) { ./Lens/CompoundLens.sol:166: for (uint i = 0; i < cTokenCount; i++) { ./Lens/CompoundLens.sol:211: for (uint i = 0; i < cTokenCount; i++) { ./Lens/CompoundLens.sol:235: for (uint i = 0; i < cTokenCount; i++) { ./Lens/CompoundLens.sol:268: for (uint i = 0; i < proposalCount; i++) { ./Lens/CompoundLens.sol:290: for (uint i = 0; i < proposalCount; i++) { ...
solidity 0.8.4 introduces custom errors which are cheaper than using revert strings in terms of gas. This can be used to save gas.
for eg.
// Before require(condition, "Revert strings"); // After error CustomError(); if (!condition) { revert CustomError(); }
more details can be found here
#0 - GalloDaSballo
2022-08-04T00:07:59Z
Less than 500 gas