NFTBridge
60,000 USDC
View results
Submission Details
Severity: high
Invalid

Unchecked Memory Allocation Leading to Memory Exhaustion in Token Bridging Protocol

Summary

The requestSerialize function in the Protocol library is vulnerable to unchecked memory allocation due to the lack of input validation on array sizes. This can lead to memory exhaustion and potential denial of service when handling excessively large requests.

Vulnerability Details

https://github.com/Cyfrin/2024-07-ark-project/blob/273b7b94986d3914d5ee737c99a59ec8728b1517/apps/blockchain/ethereum/src/Protocol.sol#L207-L239

The function calculates the required buffer size based on the lengths of various arrays within a Request structure. Without proper checks, this can result in an attempt to allocate more memory than is available, causing a memory out-of-gas error.

function requestSerialize(
Request memory req
)
internal
pure
returns (uint256[] memory)
{
@=> uint256[] memory buf = new uint256[](requestSerializedLength(req));
// Constant length part of the request.
buf[0] = felt252.unwrap(req.header);
buf[1] = uint128(req.hash);
buf[2] = uint128(req.hash >> 128);
buf[3] = uint256(uint160(req.collectionL1));
buf[4] = snaddress.unwrap(req.collectionL2);
buf[5] = uint256(uint160(req.ownerL1));
buf[6] = snaddress.unwrap(req.ownerL2);
// Variable length part of the request.
uint256 offset = 7;
offset += Cairo.cairoStringSerialize(req.name, buf, offset);
offset += Cairo.cairoStringSerialize(req.symbol, buf, offset);
offset += Cairo.cairoStringSerialize(req.uri, buf, offset);
offset += Cairo.uint256ArraySerialize(req.tokenIds, buf, offset);
offset += Cairo.uint256ArraySerialize(req.tokenValues, buf, offset);
offset += Cairo.cairoStringArraySerialize(req.tokenURIs, buf, offset);
offset += Cairo.uint256ArraySerialize(req.newOwners, buf, offset);
return buf;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "forge-std/Test.sol";
import "../src/Protocol.sol";
import "../src/sn/Cairo.sol";
contract ProtocolTest is Test {
using Cairo for uint256;
Request request;
function setUp() public {
// Initialize the request with large array sizes
uint256 largeSize = 2**16; // Using a large but manageable size
request = Request({
header: Cairo.felt252Wrap(0),
hash: 0,
collectionL1: address(0),
collectionL2: Cairo.snaddressWrap(0),
ownerL1: address(0),
ownerL2: Cairo.snaddressWrap(0),
name: "",
symbol: "",
uri: "",
tokenIds: new uint256[](largeSize),
tokenValues: new uint256[](largeSize),
tokenURIs: new string[](largeSize),
newOwners: new uint256[](largeSize)
});
}
function testRequestSerialize() public {
// This should fail due to excessive memory allocation
vm.expectRevert();
Protocol.requestSerialize(request);
}
}
forge test --match-path test/ProtocolTest.t.sol -vvvv
[⠊] Compiling...
[⠊] Compiling 1 files with Solc 0.8.26
[⠒] Solc 0.8.26 finished in 923.85ms
Compiler run successful with warnings:
Warning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.
--> src/token/TokenUtil.sol:114:9:
|
114 | address collection
| ^^^^^^^^^^^^^^^^^^
Warning (2018): Function state mutability can be restricted to pure
--> src/token/TokenUtil.sol:113:5:
|
113 | function erc1155Metadata(
| ^ (Relevant source part starts here and spans across multiple lines).
Ran 1 test for test/ProtocolTest.t.sol:ProtocolTest
[PASS] testRequestSerialize() (gas: 847120396)
Traces:
[847120396] ProtocolTest::testRequestSerialize()
├─ [0] VM::expectRevert(custom error f4844814:)
│ └─ ← [Return]
└─ ← [MemoryOOG] EvmError: MemoryOOG
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 998.23ms (598.38ms CPU time)
Ran 1 test suite in 999.53ms (998.23ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)

Impact

  • Users may experience disruptions in service as the contract could become unresponsive or revert transactions due to memory exhaustion.

  • Users attempting to interact with the contract during an attack may incur higher gas fees as their transactions fail or require multiple attempts to succeed.

  • The contract's inability to process requests efficiently could lead to delays in transaction confirmations.

  • Users relying on timely token bridging might face financial losses due to delayed or failed transactions.

  • Repeated exploitation of this vulnerability could contribute to network congestion, affecting not only the users of this contract but also other users on the network.

Tools Used

  • Manual review

  • Foundry

Recommendations

  • Implement strict checks on the size of arrays within the Request structure to ensure they do not exceed reasonable limits.

  • Define and enforce maximum allowable sizes for each array in the Request to prevent excessive memory allocation.

Updates

Lead Judging Commences

n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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