Y2k Finance contest - ak1's results

A suite of structured products for assessing pegged asset risk.

General Information

Platform: Code4rena

Start Date: 14/09/2022

Pot Size: $50,000 USDC

Total HM: 25

Participants: 110

Period: 5 days

Judge: hickuphh3

Total Solo HM: 9

Id: 162

League: ETH

Y2k Finance

Findings Distribution

Researcher Performance

Rank: 26/110

Findings: 4

Award: $253.02

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: rbserver

Also found by: Chom, ak1, nalus, robee

Labels

bug
duplicate
2 (Med Risk)
partial-50

Awards

155.5605 USDC - $155.56

External Links

Lines of code

https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/Vault.sol#L407 https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/Vault.sol#L419

Vulnerability details

Impact

When division operation is done before multiplication, the resultant can be a zero value output.

Proof of Concept

https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/Vault.sol#L419

https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/Vault.sol#L407

entitledAmount = amount.divWadDown(idFinalTVL[id]).mulDivDown( idClaimTVL[id], 1 ether );

In above line of codes, division is performed before multilication.

Tools Used

Manual code review.

It is recommended to multiply before doing division.

#0 - HickupHH3

2022-10-29T03:30:58Z

partial credit as the math is actually doing multiplication before division: see https://github.com/code-423n4/2022-09-y2k-finance-findings/issues/190#issuecomment-1281775341

however, the issue is valid because the divisor can be large enough to cause the output to be zero, as #378 explains.

Findings Information

Awards

8.0071 USDC - $8.01

Labels

bug
duplicate
2 (Med Risk)
resolved
sponsor confirmed
satisfactory

External Links

Lines of code

https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/oracles/PegOracle.sol#L46-L83

Vulnerability details

Impact

The calculated price1 could be negative or outdated one. This could affects the codes places wherever the latestRoundData is used to determine the price. one of the place is in Controller.sol#L261 - function getLatestPrice(address _token)

Proof of Concept

https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/oracles/PegOracle.sol#L46-L83

function latestRoundData() public view returns ( uint80 roundID, int256 nowPrice, uint256 startedAt, uint256 timeStamp, uint80 answeredInRound ) { ( uint80 roundID1, int256 price1, uint256 startedAt1, uint256 timeStamp1, uint80 answeredInRound1 ) = priceFeed1.latestRoundData(); int256 price2 = getOracle2_Price(); if (price1 > price2) { nowPrice = (price2 * 10000) / price1; } else { nowPrice = (price1 * 10000) / price2; } int256 decimals10 = int256(10**(18 - priceFeed1.decimals())); nowPrice = nowPrice * decimals10; return ( roundID1, nowPrice / 1000000, startedAt1, timeStamp1, answeredInRound1 ); }

In above function, the price1 is directly get from the latestRoundData of the chainlink oracle.

The returned price value could be negative or outdated one.

Tools Used

VS code

To calculate the price1, use the function getOracle1_Price that is already implemented. It has all the checks for negative and outdated. https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/oracles/PegOracle.sol#L89

#0 - 3xHarry

2022-09-21T12:04:11Z

@MiguelBits seems to be valid

#1 - MiguelBits

2022-09-21T18:25:06Z

It is, implementing this.

#2 - HickupHH3

2022-10-17T04:27:39Z

dup of #61

Lines of code

https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/Vault.sol#L152-L162

Vulnerability details

Impact

Due to buggy front end or user error, the deposited asset can be sent to zero address.

Proof of Concept

https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/Vault.sol#L152-L162.

function deposit( uint256 id, uint256 assets, address receiver ) public override marketExists(id) epochHasNotStarted(id) nonReentrant returns (uint256 shares)

In above code snippet from deposit function, receiver will receive the minted share of tokens. By chance, if the receiver does not given as input, the minted tokens will end up in dead address (zero address).

Tools Used

Manual code review.

Add validation check for receiver in the deposit function.

#0 - HickupHH3

2022-10-29T03:32:45Z

sanity check should be QA. downgrading.

warden's primary QA.

  1. Get value once and use it wherever needed. https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/Controller.sol#L96-L99 if( vault.strikePrice() < getLatestPrice(vault.tokenInsured()) ) revert PriceNotAtStrikePrice(getLatestPrice(vault.tokenInsured()));

call the getLatestPrice(vault.tokenInsured() once and use the result value in other places.

  1. No need to initialize as zero in constructor. The default value itself is zero. https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/VaultFactory.sol#L159

#0 - HickupHH3

2022-11-08T02:35:13Z

First suggestion is pretty substantial in gas savings of about 11.8k

testFailEpochExpired() (gas: 11 (0.000%)) testFailEpochNotStarted() (gas: 11 (0.000%)) testWithdrawDepeg() (gas: 13 (0.000%)) testControllerDepeg() (gas: 13 (0.000%)) testTriggerEndEpoch() (gas: -11827 (-0.085%)) testSequencerDown() (gas: -11827 (-0.155%)) testFailPriceNotAtStrikePrice() (gas: -11902 (-0.202%)) testCreateController() (gas: -11827 (-0.754%)) Overall gas change: -47361 (-1.195%)

Second one as well, 2k gas

testAddressFactoryNotInController() (gas: -2209 (-0.052%)) 
testAddressNotAdmin() (gas: -2209 (-0.052%)) 
Overall gas change: -6627 (-0.155%)
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