Notional x Index Coop - kenzo's results

A collaboration between Notional and Index Coop to create fixed rate yield index tokens.

General Information

Platform: Code4rena

Start Date: 07/06/2022

Pot Size: $75,000 USDC

Total HM: 11

Participants: 77

Period: 7 days

Judge: gzeon

Total Solo HM: 7

Id: 124

League: ETH

Notional

Findings Distribution

Researcher Performance

Rank: 10/77

Findings: 2

Award: $1,894.40

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: xiaoming90

Also found by: GreyArt, berndartmueller, jonah1005, kenzo, minhquanym

Labels

bug
duplicate
3 (High Risk)
disagree with severity

Awards

1806.2399 USDC - $1,806.24

External Links

Lines of code

https://github.com/code-423n4/2022-06-notional-coop/blob/main/notional-wrapped-fcash/contracts/wfCashERC4626.sol#L85 https://github.com/code-423n4/2022-06-notional-coop/blob/main/notional-wrapped-fcash/contracts/wfCashERC4626.sol#L21 https://github.com/code-423n4/2022-06-notional-coop/blob/main/notional-wrapped-fcash/contracts/wfCashERC4626.sol#L23 https://github.com/code-423n4/2022-06-notional-coop/blob/main/notional-wrapped-fcash/contracts/wfCashERC4626.sol#L71

Vulnerability details

EIP4626 states that maxWithdraw, convertToAssets, convertToShares, previewRedeem and previewWithdraw must not revert (unless due to large input, or due to a reason that will make deposit/redeem revert). However, wfCash4626's implementation of those ends up calling _getMaturedValue if the asset has matured. This call will revert if the account has not been settled yet.

Impact

Incorrect implementation of EIP4626. Protocols that will build upon wfCash4626 may revert unexpectedly.

Proof of Concept

All these functions end up calling _getMaturedValue via totalAssets. getMaturedValue will revert if the account has not been settled yet:

// We cannot settle an account in a view method, so this may fail if the account has not been settled // after maturity. This can be done by anyone so it should not be an issue (int256 cashBalance, /* */, /* */) = NotionalV2.getAccountBalance(currencyId, address(this)); int256 underlyingExternal = NotionalV2.convertCashBalanceToExternal(currencyId, cashBalance, true); require(underlyingExternal > 0, "Must Settle");

Therefore, the functions don't implement EIP4626 correctly, and integration with wfCash might fail.

Create a view method that will simulate the settlement of an account and get the cash balance of the account's currencyId. Then use that cashBalance to calculate the underlyingExternal.

#0 - berndartmueller

2022-06-15T09:21:36Z

Duplicate of #215 - [L-09] wfCashERC4626 contract does not conform to EIP4626

(Disclaimer: That's my QA report)

I explicitly did not submit this finding as medium severity as I thought it does not qualify:

2 β€” Med: Assets not at direct risk, but the function of the protocol or its availability could be impacted, or leak value with a hypothetical attack path with stated assumptions, but external requirements.

#1 - jeffywu

2022-06-15T13:06:00Z

Agree that this can be a QA report, there is no way for this to result in loss of funds.

#2 - gzeoneth

2022-06-26T14:51:36Z

This might be controversial but I consider this as a duplicate of #155. EIP4626 is aimed to create a consistent and robust implementation patterns for Tokenized Vaults. A slight deviation from 4626 would broke composability and potentially lead to loss of fund (POC in #88 can be an example). It is counterproductive to implement EIP4626 but does not conform to it fully.

Lines of code

https://github.com/code-423n4/2022-06-notional-coop/blob/main/notional-wrapped-fcash/contracts/wfCashERC4626.sol#L192

Vulnerability details

withdraw will revert if the account has not been settled yet. This is just due to the implementation and can be avoided by, well, settling the account.

Impact

withdraw reverts unnecessarily. Protocols and users which will use wfCash4626 will have to discover this and settle by themselves.

Proof of Concept

withdraw calls previewWithdraw, which ends up calling _getMaturedValue, which will revert if the account is not settled yet.

Add to withdraw:

NotionalV2.settleAccount(address(this));

This will ensure that the account is settled and withdraw will not revert.

#0 - jeffywu

2022-06-15T13:04:05Z

Agree, good find.

There is no loss of funds or functionality here so I would suggest that this is reduced to a QA suggestion, but a good one.

#1 - gzeoneth

2022-06-26T15:46:14Z

As warden's QA report.

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