Vader Protocol contest - defsec's results

Liquidity Protocol anchored by Native Stablecoin with Slip-Based Fees AMM, IL protection and Synthetics.

General Information

Platform: Code4rena

Start Date: 09/11/2021

Pot Size: $75,000 USDC

Total HM: 57

Participants: 27

Period: 7 days

Judge: alcueca

Total Solo HM: 49

Id: 52

League: ETH

Vader Protocol

Findings Distribution

Researcher Performance

Rank: 10/27

Findings: 5

Award: $2,689.64

🌟 Selected for report: 9

πŸš€ Solo Findings: 2

Findings Information

🌟 Selected for report: jonah1005

Also found by: defsec

Labels

bug
duplicate
3 (High Risk)
sponsor disputed
VaderPoolFactory

Awards

728.5837 USDC - $728.58

External Links

Handle

defsec

Vulnerability details

Impact

During the code review, It has been seen that createPool function does not have access control.

Proof of Concept

  1. Navigate to the following contract. createPool function does not have access control mechanism.

"https://github.com/code-423n4/2021-11-vader/blob/main/contracts/dex/pool/VaderPoolFactory.sol#L54"

Tools Used

none

Consider to put access control on the createPool function.

#0 - SamSteinGG

2021-11-25T12:12:50Z

This is equivalent to the pool factory of Uniswap without any access control.

#1 - alcueca

2021-12-11T06:28:38Z

I can't see an issue from removing the access control, but the sponsor might want to check for possible DoS or front-running attack vectors. Invalid.

#2 - alcueca

2021-12-11T06:43:55Z

Duplicate of #98. There you have the DoS attack.

#3 - alcueca

2021-12-11T06:45:02Z

Also setting a severity of 3, because it can effectively stop the protocol from creating new pools, and therefore function.

Findings Information

🌟 Selected for report: defsec

Labels

bug
2 (Med Risk)
sponsor confirmed
TwapOracle

Awards

485.7225 USDC - $485.72

External Links

Handle

defsec

Vulnerability details

Impact

The consult function in the contract TwapOracle.sol fetches the asset price from a Chainlink aggregator using the latestRoundData function. However, there are no checks on timeStamp, resulting in stale prices. The oracle wrapper calls out to a chainlink oracle receiving the latestRoundData(). It then checks freshness by verifying that the answer is indeed for the last known round. The returned updatedAt timestamp is not checked.

If there is a problem with chainlink starting a new round and finding consensus on the new value for the oracle (e.g. chainlink nodes abandon the oracle, chain congestion, vulnerability/attacks on the chainlink system) consumers of this contract may continue using outdated stale data (if oracles are unable to submit no new round is started)

Proof of Concept

  1. Navigate to "https://github.com/code-423n4/2021-11-vader/blob/607d2b9e253d59c782e921bfc2951184d3f65825/contracts/twap/TwapOracle.sol#L141" contract.

  2. consult function does not check timestamp on the latestRoundData.

Tools Used

None

Consider to add checks on the return data with proper revert messages if the price is stale or the round is incomplete, for example:

(uint80 roundID, int256 price, , uint256 timeStamp, uint80 answeredInRound) = ETH_CHAINLINK.latestRoundData(); require(timeStamp != 0, "...");

Consider checking the oracle responses updatedAt value after calling out to chainlinkOracle.latestRoundData() verifying that the result is within an allowed margin of freshness.

https://docs.chain.link/docs/faq/#how-can-i-check-if-the-answer-to-a-round-is-being-carried-over-from-a-previous-round

https://blog.openzeppelin.com/secure-smart-contract-guidelines-the-dangers-of-price-oracles/

#0 - SamSteinGG

2021-12-22T07:40:57Z

The TWAP oracle module has been completely removed and redesigned from scratch as LBTwap that is subject of the new audit.

Findings Information

🌟 Selected for report: defsec

Labels

bug
duplicate
2 (Med Risk)
GovernorAlpha

Awards

485.7225 USDC - $485.72

External Links

Handle

defsec

Vulnerability details

Impact

On the GovernorAlpha contract, function veto has been added. Although the function behaviour is expected, duplicate veto process has not been checked on that function.

Proof of Concept

  1. Navigate to following contract line. (https://github.com/code-423n4/2021-11-vader/blob/607d2b9e253d59c782e921bfc2951184d3f65825/contracts/governance/GovernorAlpha.sol#L562)
function veto(uint256 proposalId, bool support) external onlyCouncil { ProposalState _state = state(proposalId); require( _state == ProposalState.Active || _state == ProposalState.Pending, "GovernorAlpha::veto: Proposal can only be vetoed when active" ); Proposal storage proposal = proposals[proposalId]; address[] memory _targets = proposal.targets; for (uint256 i = 0; i < _targets.length; i++) { if (_targets[i] == address(this)) { revert( "GovernorAlpha::veto: council cannot veto on proposal having action with address(this) as target" ); } } VetoStatus storage _vetoStatus = proposal.vetoStatus; _vetoStatus.hasBeenVetoed = true; _vetoStatus.support = support; if (support) { queue(proposalId); } emit ProposalVetoed(proposalId, support); } /**
  1. The veto progress can be completed per proposal twice.

Tools Used

None

Consider to check if proposals vetoed before.

VetoStatus storage _vetoStatus = proposal.vetoStatus; require(!_vetoStatus.hasBeenVetoed, "Vetoed before");

#0 - SamSteinGG

2021-11-20T06:55:17Z

Duplicate of #61

#1 - alcueca

2021-12-10T14:53:40Z

Not a duplicate

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