Canto contest - 0xf15ers's results

Execution layer for original work.

General Information

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

Canto

Findings Distribution

Researcher Performance

Rank: 5/59

Findings: 8

Award: $4,445.77

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Ruhum

Also found by: 0xf15ers, Soosh, WatchPug, cccz, hake

Labels

bug
duplicate
3 (High Risk)

Awards

1987.1989 CANTO - $320.93

320.9326 USDC - $320.93

External Links

Lines of code

https://github.com/Plex-Engineer/lending-market/blob/ab31a612be354e252d72faead63d86b844172761/contracts/Comptroller.sol#L1469-L1472

Vulnerability details

Impact

The hardcoded return value is the address of COMP token in mainnet not of WETH in getWETHAddress().

Proof of Concept


 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;
    }

Tools Used

  • Manual analyis and Etherscan

#0 - ecmendenhall

2022-06-21T21:55:14Z

#1 - nivasan1

2022-06-21T22:17:33Z

duplicate of issue #242

Findings Information

🌟 Selected for report: hansfriese

Also found by: 0xf15ers

Labels

bug
duplicate
3 (High Risk)
upgraded by judge

Awards

1467.456 USDC - $1,467.46

9086.4148 CANTO - $1,467.46

External Links

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

  1. allowance(address owner, address spender) in WETH.sol returns 0 always https://github.com/Plex-Engineer/lending-market/blob/b93e2867a64b420ce6ce317f01c7834a7b6b17ca/contracts/WETH.sol#L103-L104 It's missing keyword return // recommendation
function allowance(address owner, address spender) external view returns (uint256) { return _allowance[owner][spender]; }

Findings Information

🌟 Selected for report: csanuragjain

Also found by: 0xf15ers, gzeon

Labels

bug
duplicate
2 (Med Risk)

Awards

1635.5547 CANTO - $264.14

264.1421 USDC - $264.14

External Links

Lines of code

https://github.com/Plex-Engineer/lending-market/blob/b93e2867a64b420ce6ce317f01c7834a7b6b17ca/contracts/CNote.sol#L96-L129

Vulnerability details

Impact

  • repayAmountFinal is not used inside repayBorrowFresh()
  • The computation for actualRepayAmount doesnot account for repayAmountFinal in L111.

Proof of Concept

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);
        ..........
        }

Tools Used

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

Awards

687.9945 CANTO - $111.11

124.2387 USDC - $124.24

Labels

bug
QA (Quality Assurance)

External Links

1. Unused local variables, function parameters

  • In getBorrowRate, the paramters uint cash, uint borrows, uint reserves are not used inside the function.
  • in NoteInterest.sol#L109, uint reserveFactorMantissa parameter is unsused.

2. Unused modifier

  • The modifer OnlyUniGov is not used anywher inside the contract Proposal-Store.sol

3. Misleading/Random comments

4. function visibility can be restricted to pure and view

5. Add proper revert string in require()

6. No events emitted for important updates

7. allowance(address owner, address spender) in WETH.sol returns 0 always

// recommendation
function allowance(address owner, address spender) external view returns (uint256) {
	    return _allowance[owner][spender];
    }

#0 - GalloDaSballo

2022-08-01T23:11:39Z

1. Unused local variables, function parameters

Valid NC

2. Unused modifier

Valid Refactoring

3. Misleading/Random comments

Valid NC

4. function visibility can be restricted to pure and view

Valid Ref

5. Add proper revert string in require()

Valid NC

6. No events emitted for important updates

Valid NC

7. allowance(address owner, address spender) in WETH.sol returns 0 always

Valid Low

TODO -> Bump Allowance

Neat report, great format

1L 2R 4NC

Awards

41.2642 USDC - $41.26

396.9199 CANTO - $64.10

Labels

bug
G (Gas Optimization)

External Links

1. Default vaule initialisation can be omitted

2. Use revert string < 32 bytes to save gas

3. Cache array length in loops instead of computing length in every iteration

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++) {

4. Prefix increment (++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++) {
...
5. Use solidity custom errors to save gas

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

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter