Vader Protocol contest - s1m0's results

Capital efficient liquidity protocol

General Information

Platform: Code4rena

Start Date: 22/04/2021

Pot Size: $120,000 USDC

Total HM: 41

Participants: 10

Period: 7 days

Judge: LSDan

Total Solo HM: 28

Id: 5

League: ETH

Vader Protocol

Findings Distribution

Researcher Performance

Rank: 6/10

Findings: 10

Award: $4,794.11

🌟 Selected for report: 7

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: cmichel

Also found by: 0xRajeev, s1m0

Labels

bug
duplicate
3 (High Risk)
addressed

Awards

8.7993 VETH - $457.56

0.2112 ETH - $527.96

External Links

Handle

s1m0

Vulnerability details

Impact

A proposal can be cancelled by anyone if only exist another proposal with the same type and hasMinority() (has > 16% votes).

Proof of Concept

1 voteProposal() assume this vote trigger _finalise(). _finalise() set mapPID_finalising[_proposalID] = true 2 cancelProposal()

This works only if cancelProposal is called before finaliseProposal() but the require on line 112 helps giving the attacker at least 1 block of advantage because cancelProposal() doesn't have requirement of time and can be called in the same block of step 1.

Tools Used

Manual analysis

Rethink the design of cancelProposal(). One idea that came to my mind would be to have more than 1 person to call cancelProposal() to be valid e.g. 1% of the votes for the newProposal + a number of different address who voted in the newProposal because 1 address could have 1% of the votes.

#2 - dmvt

2021-05-26T22:15:25Z

duplicate of #227

Findings Information

🌟 Selected for report: cmichel

Also found by: s1m0

Labels

bug
duplicate
3 (High Risk)

Awards

8.7993 VETH - $457.56

0.2112 ETH - $527.96

External Links

Handle

s1m0

Vulnerability details

Impact

The formula doesn't coincide with the comment.

Proof of Concept

https://github.com/code-423n4/2021-04-vader/blob/main/vader-protocol/contracts/Utils.sol#L266

Tools Used

Manual analysis.

Correct the code or the comment.

#0 - dmvt

2021-05-26T22:17:56Z

duplicate of #214

Findings Information

🌟 Selected for report: cmichel

Also found by: 0xRajeev, s1m0

Labels

bug
duplicate
3 (High Risk)

Awards

8.7993 VETH - $457.56

0.2112 ETH - $527.96

External Links

Handle

s1m0

Vulnerability details

Impact

The formula is different from the comment, the impact could be high if the comment was actually rigth.

Proof of Concept

https://github.com/code-423n4/2021-04-vader/blob/main/vader-protocol/contracts/Utils.sol#L239 is different from comment on line 234. Should be _units = ((P * (part1 + part2)) / part3) if the comment is rigth.

Tools Used

Manual analysis

Correct the code or the comment.

#0 - dmvt

2021-05-26T22:19:37Z

duplicate of #204

Findings Information

🌟 Selected for report: cmichel

Also found by: pauliax, s1m0

Labels

bug
duplicate
disagree with severity
2 (Med Risk)
sponsor confirmed

Awards

2.6398 VETH - $137.27

0.0634 ETH - $158.39

External Links

Handle

s1m0

Vulnerability details

Impact

The mapPID_finalised is set on completeProposal() but voteProposal() doesn't check it. A malicious user with enough capital and/or together with other people could execute a proposal in his favor (e.g. a grant) infinitely.

Proof of Concept

https://github.com/code-423n4/2021-04-vader/blob/main/vader-protocol/contracts/DAO.sol#L131 1 newGrantProposal() 2 voteProposal() until enough votes 3 finaliseProposal() -> grantFunds() -> completeProposal() 4 repeat

Tools Used

Manual analysis.

In voteProposal() require(!mapPID_finalised[proposalID], "Proposal already executed")

#0 - strictly-scarce

2021-05-01T13:25:13Z

If they have this weighting in the DAO, then they can pass another proposal of same nature.

GRANT funding is rate-limited for this reason.

#1 - strictly-scarce

2021-05-01T13:25:59Z

However seems wise to add this check to force a new proposal

#4 - dmvt

2021-05-26T22:46:29Z

duplicate of #229

Findings Information

🌟 Selected for report: s1m0

Also found by: 0xRajeev, JMukesh, a_delamo, cmichel

Labels

bug
disagree with severity
1 (Low Risk)
sponsor acknowledged
sponsor confirmed

Awards

0.4276 VETH - $22.24

0.0103 ETH - $25.66

External Links

#0 - strictly-scarce

2021-05-01T13:04:12Z

The ethereum state machine isn't a parking lot for event data

  • setParams() - no, plenty events in DAO
  • setAnchorParams() - no, plenty events in DAO

But these are warranted, purely for off-chain metrics:

  • addDepositData() - valid for off-chain IL tracking
  • removeDepositData() - valid for off-chain IL tracking

#1 - strictly-scarce

2021-05-01T13:04:46Z

Severity: 0, no impact to protocol itself

Findings Information

🌟 Selected for report: pauliax

Also found by: s1m0

Labels

bug
duplicate
1 (Low Risk)

Awards

1.4666 VETH - $76.26

0.0352 ETH - $87.99

External Links

Handle

s1m0

Vulnerability details

Impact

The blockDelay variable is not set so at deploy time the flashProof() modifier doesn't work as expected.

Proof of Concept

https://github.com/code-423n4/2021-04-vader/blob/main/vader-protocol/contracts/USDV.sol#L41

Tools Used

Manual analysis

Set the blockDelay in the init() with a predefined value or through an argument.

#0 - dmvt

2021-05-24T13:17:44Z

duplicate of #307

Findings Information

🌟 Selected for report: s1m0

Also found by: 0xRajeev

Labels

bug
1 (Low Risk)

Awards

1.4666 VETH - $76.26

0.0352 ETH - $87.99

External Links

Handle

s1m0

Vulnerability details

Impact

The token can be sent to address(0) through a normal transfer() without decreasing the totalSupply as it would with calling burn() and it could cause an unintentional burn.

Proof of Concept

https://github.com/code-423n4/2021-04-vader/blob/main/vader-protocol/contracts/Vader.sol#L122 https://github.com/code-423n4/2021-04-vader/blob/main/vader-protocol/contracts/USDV.sol#L102

Tools Used

Manual analysis

Consider checking the recipient address to be != address(0).

Findings Information

🌟 Selected for report: s1m0

Labels

bug
1 (Low Risk)

Awards

3.259 VETH - $169.47

0.0782 ETH - $195.54

External Links

Handle

s1m0

Vulnerability details

Impact

voteProposal() doesn't check that proposalID <= proposalCount.

Proof of Concept

https://github.com/code-423n4/2021-04-vader/blob/main/vader-protocol/contracts/DAO.sol#L79

Tools Used

Manual analysis

in voteProposal() require(proposalID <= proposalCount, "Proposal not existent") should be <= because proposalCount is updated before using it (e.g. https://github.com/code-423n4/2021-04-vader/blob/main/vader-protocol/contracts/DAO.sol#L59) in this way the proposal n. 0 is not assignable i'm not sure if it's wanted or not.

Findings Information

🌟 Selected for report: toastedsteaksandwich

Also found by: 0xRajeev, s1m0

Labels

bug
duplicate
1 (Low Risk)
sponsor acknowledged

Awards

0.8799 VETH - $45.76

0.0211 ETH - $52.80

External Links

Handle

s1m0

Vulnerability details

Impact

Vader, USDV and VETH are vulnerable to double-spend allowance attack in which an attacker can front-run the execution of an approve() function.

Proof of Concept

Tools Used

Manual analysis

Consider implementing increaseAllowance() and decreaseAllowance().

#0 - strictly-scarce

2021-05-01T13:32:03Z

hypothetical

#1 - dmvt

2021-05-26T22:44:25Z

duplicate of #35

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