DeFiHardhatFoundry
250,000 USDC
View results
Submission Details
Severity: high
Invalid

`paste32Bytes` in `LibBytes.sol` doesn't work correctly

Summary

paste32Bytes in LibBytes.sol doesn't work correctly

Vulnerability Details

function paste32Bytes(bytes memory copyFromData, bytes memory pasteToData, uint256 copyIndex, uint256 pasteIndex)
internal
pure
{
assembly {
mstore(add(pasteToData, pasteIndex), mload(add(copyFromData, copyIndex)))
}
}

paste32Bytes is used to copy 32 Bytes from copyFromData at copyIndex and paste into pasteToData at pasteIndex. However bytes memory variables in Solidity have an additional 32 bytes of overhead for storing the array length. Adding 0x20 (which is 32 in decimal) ensures that the pointer point to the actual data within the byte array, skipping this overhead. This is crucial for accurate byte manipulation, as directly accessing memory locations without considering the overhead could lead to incorrect data or out-of-bounds exceptions.

POC

Test code below in remix:

/**
* SPDX-License-Identifier: MIT
*
*/
pragma solidity ^0.8.20;
contract BytesMemory {
function paste32Bytes(
bytes memory copyFromData,
bytes memory pasteToData,
uint256 copyIndex,
uint256 pasteIndex
) public pure returns(bytes memory) {
// Ensure the source has enough bytes to copy
require(copyFromData.length >= copyIndex + 32, "copyFromData out of range");
// Ensure the destination has enough space to paste
require(pasteToData.length >= pasteIndex + 32, "pasteToData out of range");
// Use inline assembly to copy 32 bytes from source to destination
assembly {
// Calculate the memory addresses
let source := add(add(copyFromData, 0x20), copyIndex)
let destination := add(add(pasteToData, 0x20), pasteIndex)
// Load 32 bytes from the source and store them into the destination
let data := mload(source)
mstore(destination, data)
}
return pasteToData;
}
function paste32BytesV2(
bytes memory copyFromData,
bytes memory pasteToData,
uint256 copyIndex,
uint256 pasteIndex
) public pure returns(bytes memory) {
assembly {
mstore(add(pasteToData, pasteIndex), mload(add(copyFromData, copyIndex)))
}
return pasteToData;
}
}

Input:
copyFromData: "0x1111111111111111111111111111111111111111111111111111111111111111"
pasteToData: "0x2222222222222222222222222222222222222222222222222222222222222222"
copyIndex: 0
pasteIndex: 0
Output:
paste32Bytes: 0x1111111111111111111111111111111111111111111111111111111111111111
paste32BytesV2: 0x2222222222222222222222222222222222222222222222222222222222222222
Conclusion:
paste32Bytes is working correctly and paste32BytesV2 not

Impact

pasteBytesTractor and pasteBytesClipboard don't work correctly

Tools Used

manual and remix

Recommendations

function paste32Bytes(bytes memory copyFromData, bytes memory pasteToData, uint256 copyIndex, uint256 pasteIndex)
internal
pure
{
+ assembly {
+ let src := add(add(copyFromData, 0x20), copyIndex)
+ let dest := add(add(pasteToData, 0x20), pasteIndex)
+ mstore(dest, mload(src))
+ }
- assembly {
- mstore(add(pasteToData, pasteIndex), mload(add(copyFromData, copyIndex)))
- }
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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