Canto contest - Tutturu'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: 11/59

Findings: 7

Award: $2,423.58

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Tutturu

Also found by: 0x52, WatchPug, hyh, p4st13r4

Labels

bug
3 (High Risk)
sponsor confirmed

Awards

2649.5985 CANTO - $427.91

427.9102 USDC - $427.91

External Links

Lines of code

https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/CNote.sol#L43 https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/CNote.sol#L114 https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/CNote.sol#L198 https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/CNote.sol#L310

Vulnerability details

Impact

The contract expects the balance of the underlying token to == 0 at all points when calling the contract functions by requiring getCashPrior() == 0, which checks token.balanceOf(address(this)) where token is the underlying asset.

An attacker can transfer any amount of the underlying asset directly to the contract and make all of the functions requiring getCashPrior() == 0 to revert.

Proof of Concept

CNote.sol#L43 CNote.sol#L114 CNote.sol#198 CNote.sol#310

  1. Attacker gets any balance of Note (amount = 1 token)
  2. Attacker transfers the token to CNote which uses Note as an underlying asset, by calling note.transfer(CNoteAddress, amount). The function is available since Note inherits from ERC20
  3. Any calls to CNote functions now revert due to getCashPrior() not being equal to 0

Instead of checking the underlying token balance via balanceOf(address(this)) the contract could hold an internal balance of the token, mitigating the impact of tokens being forcefully transferred to the contract.

#0 - GalloDaSballo

2022-08-10T22:23:04Z

The warden has shown how, via a simple transfer of 1 wei of token, the invariant of getCashPrior() == 0 can be broken, bricking the functionality.

Because of:

  • the simplicity of the exploit
  • The impact being inability to interact with the contract
  • A protocol invariant is broken

I agree with High Severity

Mitigation would require using delta balances and perhaps re-thinking the need for those intermediary checks

Findings Information

🌟 Selected for report: WatchPug

Also found by: Lambda, Tutturu, catchup, p4st13r4

Labels

bug
duplicate
3 (High Risk)

Awards

2649.5985 CANTO - $427.91

427.9102 USDC - $427.91

External Links

Lines of code

https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/Note.sol#L13-L19

Vulnerability details

Impact

By leaving _mint_to_Accountant() with no access control when accountant = address(0) it allows an attacker to call the function, mint the entire supply to themselves, and gain the accountant and admin roles. Additionally, the parameter "address accountantDelegator" is expected but never used in the function.

Proof of Concept

Note.sol#L13

Add admin access control to the _mint_to_Accountant() function

#0 - nivasan1

2022-06-23T04:13:00Z

duplicate of #195

#1 - GalloDaSballo

2022-08-12T00:36:34Z

Dup of #173

Findings Information

🌟 Selected for report: p4st13r4

Also found by: 0x52, Tutturu

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/ab31a612be354e252d72faead63d86b844172761/contracts/CNote.sol#L14-L21

Vulnerability details

Impact

The function does not have access control before the accountant address is set, allowing anyone to call the function, gain admin privileges, and set the accountant address.

Proof of Concept

CNote.sol#L17

Include access control even when _accountant is not set or set _accountant during deployment

#0 - nivasan1

2022-06-23T04:12:33Z

duplicate of #195

#1 - GalloDaSballo

2022-08-12T00:35:42Z

Dup of #195

Awards

72.5532 USDC - $72.55

687.9945 CANTO - $111.11

Labels

bug
QA (Quality Assurance)

External Links

CNote.sol functions borrowFresh() and redeemFresh() do not follow the checks-effects-interactions pattern

  1. File CNote.sol#L76
doTransferOut(borrower, borrowAmount); require(getCashPrior() == 0,"CNote::borrowFresh: Error in doTransferOut, impossible Liquidity in LendingMarket"); //Amount minted by Accountant is always flashed from account /* We write the previously calculated values into storage */ accountBorrows[borrower].principal = accountBorrowsNew; accountBorrows[borrower].interestIndex = borrowIndex; totalBorrows = totalBorrowsNew;
  1. File CNote.sol#L332
doTransferOut(redeemer, redeemAmount); /* We write previously calculated values into storage */ totalSupply = totalSupply - redeemTokens; accountTokens[redeemer] = accountTokens[redeemer] - redeemTokens; /* We emit a Transfer event, and a Redeem event */ emit Transfer(redeemer, address(this), redeemTokens); emit Redeem(redeemer, redeemAmount, redeemTokens); /* We call the defense hook */ comptroller.redeemVerify(address(this), redeemer, redeemAmount, redeemTokens);

Mitigation: Move all state updates before doTransferOut()

Constructor visibility is unnecessary

Reason: Constructor visibility is ignored since 0.7.0 Mitigation: Remove keyword "public"

  1. File Unitroller.sol#L33
constructor() public { // Set admin to caller admin = msg.sender; }

#0 - GalloDaSballo

2022-08-03T23:45:11Z

CNote.sol functions borrowFresh() and redeemFresh() do not follow the checks-effects-interactions pattern

Valid Low

Constructor visibility is unnecessary

NC

1L 1NC

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