HardhatDeFi
15,000 USDC
View results
Submission Details
Severity: medium
Invalid

Improper Handling of `bytes32` to `string` Conversion in `_registerCollateralToken` Function

Summary

The _registerCollateralToken function in the AaveDIVAWrapperCore contract deploys a wrapped version of a collateral token (wToken) and derives its symbol by prefixing the original collateral token's symbol with "w". However, the function assumes that the symbol() function of the collateral token returns a string. For tokens like MKR, where the symbol() function returns a bytes32 value instead of a string, this assumption leads to incorrect and non-human-readable token symbols.

Vulnerability Details

NOTE-1: According to the readMe, all tokens used by aave are in scope. The following report is about an issue with "MKR" token which is a valid aave token.

registerCollateralToken function deploys a token that represents a wrapped version of the collateral token to be used as proxy collateral in DIVA Protocol. The symbol and name of the wToken are derived from the original collateral token, prefixed with 'w' (e.g., wUSDT or wUSDC).

The issue is that the function assumes that the symbol() function of the _collateralTokenContract returns a string. However, if the _collateralTokenContract is MKR token where the symbol() function returns a bytes32 instead of a string, the code will not work correctly as written. This is because abi.encodePacked("w", _collateralTokenContract.symbol()) expects the symbol to be a string, not bytes32.
AaveDIVAWrapperCore.sol#L92-L96

function _registerCollateralToken(address _collateralToken) internal returns (address) {
// ....
@> WToken _wTokenContract = new WToken(
string(abi.encodePacked("w", _collateralTokenContract.symbol())),
_collateralTokenContract.decimals(),
address(this) // wToken owner
);
// ....

In Solidity, bytes32 can be concatenated with a string using abi.encodePacked, but the result will not be human-readable without proper conversion. This is because bytes32 is a fixed-length byte array, and string is a dynamically sized UTF-8 encoded byte array. When you concatenate them directly, the result will be a byte array that combines the raw bytes of the string and the bytes32 value.

Casting this result to a string produces a non-human-readable string with embedded null bytes, which are displayed as square boxes in tools like Remix.

This is likely not what you want, as the bytes32 value will not be properly interpreted as a string unless it is explicitly converted.

A short POC to test in remix:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract PoC {
// MKR symbol in bytes32 format
bytes32 public constant MKR_SYMBOL = 0x4d4b520000000000000000000000000000000000000000000000000000000000;
// Function to demonstrate the issue with abi.encodePacked
function demonstrateIssue() public pure returns (string memory) {
// Directly concatenate "w" (string) with MKR_SYMBOL (bytes32)
// If you try to interpret this as a string, it will not be human-readable because the bytes32 value is not properly converted to a string.
return string(abi.encodePacked("w", MKR_SYMBOL));
}
// Function to show the correct way to concatenate
function demonstrateCorrectWay() public pure returns (string memory) {
// Convert bytes32 to string first
string memory symbolString = bytes32ToString(MKR_SYMBOL);
// Concatenate "w" with the converted string
// it will return a correct format
return string(abi.encodePacked("w", symbolString));
}
// Helper function to convert bytes32 to string
function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {
uint8 i = 0;
while (i < 32 && _bytes32[i] != 0) {
i++;
}
bytes memory bytesArray = new bytes(i);
for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
bytesArray[i] = _bytes32[i];
}
return string(bytesArray);
}

Steps to Reproduce:

  1. Deploy the PoC contract in Remix.

  2. Call demonstrateIssue() and observe the output: "wMKR" followed by square boxes.

  3. Call demonstrateCorrectWay() and observe the clean output: "wMKR".

Impact

Wrapped tokens will be deployed with non-standard symbols containing embedded null bytes, leading to display issues in user interfaces, interoperability problems with external systems, and potential data corruption in applications relying on clean, human-readable token symbols.

Tools Used

Manual Review

Recommendations

To resolve this issue, explicitly convert the bytes32 symbol to a string by trimming the null bytes before concatenation. Use a helper function like bytes32ToString to ensure the resulting string is clean and human-readable.

Updates

Lead Judging Commences

bube Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Appeal created

0xshoonya Submitter
9 months ago
bube Lead Judge
9 months ago
bube Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.