Yield-Convex contest - sirhashalot's results

Fixed-rate borrowing and lending on Ethereum

General Information

Platform: Code4rena

Start Date: 28/01/2022

Pot Size: $30,000 USDC

Total HM: 4

Participants: 22

Period: 3 days

Judge: GalloDaSballo

Total Solo HM: 2

Id: 80

League: ETH

Yield

Findings Distribution

Researcher Performance

Rank: 5/22

Findings: 3

Award: $1,045.22

🌟 Selected for report: 2

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: throttle

Also found by: 0x1f8b, TomFrenchBlockchain, WatchPug, cccz, defsec, hack3r-0m, hyh, kenzo, leastwood, sirhashalot, ye0lde

Labels

bug
duplicate
2 (Med Risk)

Awards

69.1238 USDC - $69.12

External Links

Handle

sirhashalot

Vulnerability details

Impact

The Chainlink latestRoundData() function is used in Cvx3CrvOracle.sol, but it is used without checking whether the data returns from the oracle is stale or not. Chainlink warns about this issue and describes how to check for it: https://docs.chain.link/docs/faq/#how-can-i-check-if-the-answer-to-a-round-is-being-carried-over-from-a-previous-round

Proof of Concept

From Cvx3CrvOracle.sol lines 120-122

(, int256 daiPrice, , , ) = DAI.latestRoundData(); (, int256 usdcPrice, , , ) = USDC.latestRoundData(); (, int256 usdtPrice, , , ) = USDT.latestRoundData();

Only the price is retrieved from the Chainlink latestRoundData() function call. This price is accepted as valid data without any checks. This can lead to using stale prices, which can be problematic in volatile market conditions. For an example of this same issue found by an audit firm, see this finding from Consensys Diligence.

Add checks for the round ID and timestamp returned by the Chainlink latestRoundData() function. For example:

(uint80 roundID, int256 daiPrice, , uint256 timestamp, uint80 answeredInRound) = DAI.latestRoundData(); require(daiPrice > 0, "Chainlink pricefeed reporting 0"); require(answeredInRound >= roundID, "Chainlink price is stale"); require(timestamp != 0, "Chainlink round incomplete");

#0 - iamsahu

2022-02-01T19:27:36Z

#136

Findings Information

🌟 Selected for report: sirhashalot

Labels

bug
G (Gas Optimization)
resolved
sponsor confirmed

Awards

95.0104 USDC - $95.01

External Links

Handle

sirhashalot

Vulnerability details

Impact

The _calcCvxIntegral() function in ConvexStakingWrapper.sol doesn't use the same gas optimization that its sibling function _calcRewardIntegral() uses.

Proof of Concept

This code is from the _calcCvxIntegral() function

if (_isClaim || userI < cvxRewardIntegral) { uint256 receiveable = cvx_claimable_reward[_accounts[u]] + ((_balances[u] * (cvxRewardIntegral - userI)) / 1e20); if (_isClaim) { if (receiveable > 0) { cvx_claimable_reward[_accounts[u]] = 0; IERC20(cvx).safeTransfer(_accounts[u], receiveable); bal = bal - (receiveable); } } else { cvx_claimable_reward[_accounts[u]] = receiveable; } cvx_reward_integral_for[_accounts[u]] = cvxRewardIntegral; }

The related code from the _calcRewardIntegral() function has the receivable calculation inside the if (_isClaim) code branch to save gas if _isClaim is false.

if (_isClaim || userI < rewardIntegral) { if (_isClaim) { uint256 receiveable = reward.claimable_reward[_accounts[u]] + ((_balances[u] * (uint256(rewardIntegral) - userI)) / 1e20); if (receiveable > 0) { reward.claimable_reward[_accounts[u]] = 0; IERC20(reward.reward_token).safeTransfer(_accounts[u], receiveable); bal = bal - receiveable; } } else { reward.claimable_reward[_accounts[u]] = reward.claimable_reward[_accounts[u]] + ((_balances[u] * (uint256(rewardIntegral) - userI)) / 1e20); } reward.reward_integral_for[_accounts[u]] = rewardIntegral; }

This optimization would save gas each time _checkpoint() is called because _checkpoint() sets _isClaim to false and doesn't enter the if(_isClaim) branch.

Modify the _calcCvxIntegral() function to place the receiveable calculation inside the if (_isClaim) code branch.

#0 - GalloDaSballo

2022-02-13T16:43:14Z

You save gas on all the operations you don't do, nice finding

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