sherlock-audit/2023-05-Index-judging

shogoki - Loss of user funds - unchecked Return of ERC20 Transfer

Opened this issue · 8 comments

shogoki

high

Loss of user funds - unchecked Return of ERC20 Transfer

Summary

Silently failing transfers can result in a partial or total loss of the users investment.

Vulnerability Detail

Some ERC20 Tokens do not revert on failure of the transfer function, but return a bool value instead. Some do not return any value. Therefore it is required to check if a value was returned, and if true, which value it is. This is not done on some places in these contracts.

The DebtIssuanceModulev2, which is required to issue or redeem tokens whenever there is a LeverageModule involved uses the invokeTransfer function of the Invoke library to transfer ERC20 Tokens from the SetToken to the user.

invokeTransfer is encoding the Calldata for the regular transfer function of ERC20 tokens and passes it together with the target (ERC20 token address) the SetTokens generic invoke function, whichin turn uses functionCallWithValue from the Openzeppelin Address Library. This method is bubbling up a possible revert of the call and returning the raw data.

The generic invoke is returning this raw data, however in invokeTransfer the return value of invoke is ignored and not used.
As some ERC20 Tokens do not revert on a failed transfer, but instead return a false bool value, the stated behaviour can lead to silently failing transfers.

This is inside the DebtIssuanceModulev2 used to:

  1. Transfer The "debt" (borrowed) Tokens to the user at Issuance
  2. Transfer back the main component Tokens (e.g. aTokens) to the user at Redemption

If such a Transfer silently fails, the funds will remain inside the setToken contract and the user has no chance to recover them.

In the issuance event the user receives the SetTokens but not the borrowed Tokens, which he has to repay when he wants to redeem the tokens. (Results in Loss of the "Debt")

In the redemption event the user repays his debt & bruns his Set Tokens, but never receives his original Tokens back. (Total Loss of investment)

Impact

Possible Loss of all/part of the Investment for the User

Code Snippet

Usage of invokeTransfer inDebtIssuanceModulev2:

https://github.com/sherlock-audit/2023-05-Index/blob/main/index-protocol/contracts/protocol/modules/v1/DebtIssuanceModuleV2.sol#L283

https://github.com/sherlock-audit/2023-05-Index/blob/main/index-protocol/contracts/protocol/modules/v1/DebtIssuanceModuleV2.sol#L315

invokeTransfer function ignores return value of invoke:

https://github.com/sherlock-audit/2023-05-Index/blob/main/index-protocol/contracts/protocol/lib/Invoke.sol#L66-L78

invoke uses functionCallwithValue and returns the raw return Data (which is ignored in this case):

https://github.com/sherlock-audit/2023-05-Index/blob/main/index-protocol/contracts/protocol/SetToken.sol#L197-L212

Tool used

Manual Review

Recommendation

Check for the existence and value of the returned data of the Transfer call. If there is a return value, it has to be true. This could be achieved by using Openzeppelins SafeERC20 library´s safeTransfer.

Escalate for 10USDC
This should be considered a valid finding.
it backs up the existing escalation on #236

There exists a risk of loosing funds due to missing checks on the transfer calls, as described in the report.

Escalate for 10USDC
This should be considered a valid finding.
it backs up the existing escalation on #236

There exists a risk of loosing funds due to missing checks on the transfer calls, as described in the report.

You've created a valid escalation for 10 USDC!

To remove the escalation from consideration: Delete your comment.

You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.

This should definitely be a duplicate of the issue that states that the protocol does not work with tokens like USDT. This is just a superset of that issue that has the same fix.

This should definitely be a duplicate of the issue that states that the protocol does not work with tokens like USDT. This is just a superset of that issue that has the same fix.

No it should not. It should be a valid issue together with duplicates like:
#155, #236 and #280

This issue is not about USDT. It is about Tokens that do not revert on failure, which can lead to a silently failed transfer.

Result:
Medium
Has duplicates
Considering this and its duplicates a separate issue as its core issue is different from #314

Escalations have been resolved successfully!

Escalation status:

Fix looks good. Non-empty return data is now checked to accommodate tokens that return false instead of reverting