Canto contest - hake'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: 3/59

Findings: 14

Award: $7,689.41

🌟 Selected for report: 3

🚀 Solo Findings: 6

Findings Information

🌟 Selected for report: Soosh

Also found by: 0x1f8b, Ruhum, TerrierLover, WatchPug, cccz, csanuragjain, hake, p4st13r4, zzzitron

Labels

bug
duplicate
3 (High Risk)

Awards

782.2807 CANTO - $126.34

126.3383 USDC - $126.34

External Links

Lines of code

https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/Governance/GovernorBravoDelegate.sol#L86

Vulnerability details

Impact

Anyone can call execute() and pass in a malicious proposal.

Proof of Concept

There is no access control for the execute() function.

Tools Used

Manual Review.

Implement access control to execute().

#0 - nivasan1

2022-06-22T20:11:00Z

Duplicate of #26

#1 - GalloDaSballo

2022-08-10T22:18:40Z

Marking as dup of 26 although this report could be argued to not be relevant

Findings Information

🌟 Selected for report: Ruhum

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

Labels

bug
duplicate
3 (High Risk)

Awards

320.9326 USDC - $320.93

1987.1989 CANTO - $320.93

External Links

Lines of code

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

Vulnerability details

Impact

getWETHAddress() still relies on same Comp hard coded address.

Unless WETH address is deployed to an address identical to Comps original address the grantCompinternal() function wont work or in a pessimistic scenario an attacker might deploy a malicious token to that address and steal users funds.

Proof of Concept

As stated in the README.md file the changes made to Comptroller.sol were made "to allow for the granting of any generic ERC-20 token as a reward instead of Comp token"

However, the modification in the grantCompInternal() function does not remove the reference to Comp(), it simply renames the parameters while still using the same Comp address at getWETHAddress().

The functionality has not changed at all, the only change made was the renaming from COMP to WETH.

Here is a link to the original Comptroller.sol where the address getCompAddress() is the same as getWETHAddress().

Additionally, the hard coded address in getWETHAddress() doesn't allow "for the granting of any generic ERC-20 token as a reward" only for WETH.

Tools Used

Manual Review.

As discussed with sponsor I recommend promptly changing the hard coded address. This seems like something really easy to overlook that could lead up to a really costly mistake.

#0 - ecmendenhall

2022-06-21T21:54:46Z

#1 - nivasan1

2022-06-22T20:41:07Z

duplicate of #46

Findings Information

🌟 Selected for report: Ruhum

Also found by: 0xmint, cccz, csanuragjain, dipp, hake, zzzitron

Labels

bug
duplicate
3 (High Risk)

Awards

247.5766 USDC - $247.58

1532.982 CANTO - $247.58

External Links

Lines of code

https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/Governance/GovernorBravoDelegate.sol#L63

Vulnerability details

Impact

Proposals might be falsely deemed as executed when in fact they have not been executed yet.

Proof of Concept

The queue() function sets newProposal.executed = true even though that is not technically true. For the proposal to be executed it needs to be called via the execute() function.

Tools Used

Manual Review.

Do not automatically set proposal state to executed when queueing as it doesnt reflect actual state of events.

#0 - nivasan1

2022-06-24T03:21:45Z

duplicate of #39

#1 - GalloDaSballo

2022-08-10T23:45:07Z

While submissions lacks some details, it does get duped up with #39

Findings Information

🌟 Selected for report: hake

Labels

bug
2 (Med Risk)
sponsor confirmed

Awards

978.304 USDC - $978.30

6057.6098 CANTO - $978.30

External Links

Lines of code

https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/Governance/GovernorBravoDelegate.sol#L115

Vulnerability details

Impact

state() function cannot view the state from any proposal except for the latest one.

Proof of Concept

require(proposalCount >= proposalId && proposalId > initialProposalId, "GovernorBravo::state: invalid proposal id");

Currently proposalCount needs to be bigger or equal to proposalId. Assuming proposalId is incremented linearly in conjunction with proposalCount, this implies only the most recent proposalId will pass the require() check above. All other proposals will not be able to have their states checked via this function.

Tools Used

Manual Review.

Change above function to proposalCount <= proposalId (assuming proposalId is set linearly, which currently is not enforced by code).

#0 - GalloDaSballo

2022-08-04T19:30:23Z

The warden has shown how, due to a mistake in logic, only the state of the latest proposal can be read.

Because the function state is used in execute we can conclude that only one proposal can be queue for execution at a time, drastically reducing the availability of the Governor.

For this reason I believe medium severity is appropriate

Findings Information

🌟 Selected for report: hake

Labels

bug
2 (Med Risk)
sponsor disputed

Awards

6057.6098 CANTO - $978.30

978.304 USDC - $978.30

External Links

Lines of code

https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/Governance/GovernorBravoDelegate.sol#L115

Vulnerability details

Impact

state() function cannot be called to view proposal state if proposalId == 0.

Proof of Concept

There is no check to prevent queueing a proposalId with a value of 0 via the queue() function. However, in the state() function there is a check preventing using a proposalId == 0. For clarity: initialProposalId must be zero according to _initiate(), therefore, proposalId cannot be 0 according to check below.

function state(uint proposalId) public view returns (ProposalState) {
    require(proposalCount >= proposalId && proposalId > initialProposalId, "GovernorBravo::state: invalid proposal id");

Tools Used

Manual Review

Implement check to preventing queueing a proposalId == 0.

#0 - nivasan1

2022-07-21T22:24:15Z

The ProposalId cannot be 0 as the proposal IDs are fixed and will be set via the cosmos-sdk.

#1 - GalloDaSballo

2022-08-04T19:39:12Z

The warden has shown how, through a misconfiguration, a proposal could never be executable due to a revert in state()

While I believe the warden has already shown a remediation that would cover this scenario, I believe the Warden has shown a unique possible situation that can cause the system to stop working as intended.

While the sponsor says the proposalId will never be 0, there is no way to avoid that at the Smart Contract level, meaning that any caller can set the proposal to 0.

For these reasons, I think Medium Severity to be appropriate

Findings Information

🌟 Selected for report: hake

Labels

bug
2 (Med Risk)
sponsor acknowledged

Awards

978.304 USDC - $978.30

6057.6098 CANTO - $978.30

External Links

Lines of code

https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/Comptroller.sol#L1376

Vulnerability details

Impact

Admin can _grantComp() to any address using any amount and drain the contract.

Proof of Concept

If admin key gets compromised there is no timelock, no amount boundaries and no address limitations to prevent the assets to be drained immediately to the attackers address.

Tools Used

Manual Review.

There is a few suggestions that could help mitigate this issue: Implement timelock for _grantComp() Implement hard coded recipient so funds cannot be arbitrarily sent to any address. Implement a limit to the amount that can be granted.

Here is a reference to a past submission where this issue has been made by team Watchpug: https://github.com/code-423n4/2022-01-insure-findings/issues/271

#0 - nivasan1

2022-06-23T02:21:29Z

We acknowledge that this is an issue, however we feel that changing the core functionality of compound would be too costly.

#1 - GalloDaSballo

2022-08-10T21:19:30Z

The warden has shown how the Admin could sweep the reward token(in this case WETH) to any address, at any time, for an amount equal to all tokens available to the Comptroller.

Because this is contingent on admin privilege, I think Medium Severity to be more appropriate

Awards

687.9945 CANTO - $111.11

215.0341 USDC - $215.03

Labels

bug
QA (Quality Assurance)

External Links

QA Report

[L-01] Floating pragma

Using a floating pragma (^) might result in the contract being deployed with a version it was not tested with and might result in bugs that affect the contract system negatively.
Locking the pragma (deleting the ^) helps to ensure that contracts do not accidentally get deployed using an outdated compiler version or a version it was not tested with. For example testing Comptroller.sol with 0.8.14, but deploying it 0.8.11 as BaseV1-core.sol uses this version

https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/Comptroller.sol#L1394 https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-core.sol#L2

[N-01] Delete comment that serves no purpose

Code not used from original BaseV1-core.sol should be removed instead of commented out for better clarity. https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-core.sol#L362

[N-02] Inconsistent naming convention

It is conventional to capitalise constants. Some constants do not follow this convention. https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/Governance/GovernorBravoDelegate.sol#L9-L12

[N-03] Error message typo

faialure -> failure. https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-periphery.sol#L463

[N-04] Unclear error message

Please be more clear with error message linked below. https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-periphery.sol#L466

[N-05] Discrepancy in repo/specs vs intended functionality

Copied from the repo: "the modification of Comptroller to allow for the granting of any generic ERC-20 token as a reward instead of Comp token"

However, as confirmed by sponsor Comptroller.sol does not intend to be able to grant "any generic ERC-20 token as a reward", only WETH.

#0 - GalloDaSballo

2022-08-02T20:36:18Z

[L-01] Floating pragma

NC

[N-01] Delete comment that serves no purpose

R

[N-02] Inconsistent naming convention

R

[N-03] Error message typo

NC

[N-04] Unclear error message

NC

[N-05] Discrepancy in repo/specs vs intended functionality

NC

2R 4NC

Awards

39.6748 USDC - $39.67

396.9199 CANTO - $64.10

Labels

bug
G (Gas Optimization)

External Links

Gas Report

[G-01] for loop gas optimisation

for (uint i = 0; i < routes.length; i++) {
    address pair = pairFor(routes[i].from, routes[i].to, routes[i].stable);
    if (IBaseV1Factory(factory).isPair(pair)) {
        amounts[i+1] = IBaseV1Pair(pair).getAmountOut(amounts[i], routes[i].from);
    }
}

Gas could be saved by:

  • Not initialising variable to default value of zero
  • Caching array length
  • Using a prefix (++i) instead of a postfix (i++)
  • Unchecking increment count

Example:

uint length = routes.length;

for (uint i; i < length;) {
    address pair = pairFor(routes[i].from, routes[i].to, routes[i].stable);
    if (IBaseV1Factory(factory).isPair(pair)) {
        amounts[i+1] = IBaseV1Pair(pair).getAmountOut(amounts[i], routes[i].from);
    }
		unchecked { ++i; }
}

https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-periphery.sol#L136

[G-02] Redundant parameter setting

Parameters are always initialed to zero as their default value, therefore assigning them a value of zero is a waist of gas.

https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/Governance/GovernorBravoDelegate.sol#L62 https://github.com/Plex-Engineer/lending-market/blob/755424c1f9ab3f9f0408443e6606f94e4f08a990/contracts/Governance/GovernorBravoDelegate.sol#L57

#0 - GalloDaSballo

2022-08-04T00:27:20Z

Less than 100 gas saved

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