# Crafted smart contract can take ~23 seconds to execute due to immense error string construction

NativeContract.execute hex-encodes the entire input into an error string, so a 1MB invalid call in a gas-burning loop stalls block execution ~23s.

- Payout: hidden
- Severity: medium
- Program: Rootstock Labs
- Found by: guido
- Disclosed: 2025-06-12
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/2559404
- Library page: https://bugbountylibrary.com/r/h1%3A2559404
- Tags: area:web3 domain:web3 impact:dos kind:bounty platform:hackerone sev:medium tech:evm tech:java technique:source-review vuln:dos

**Target:** NativeContract.execute in rskj-core (RSKJ EVM native contract call)
**Root cause:** On invalid input, NativeContract.execute builds an error message containing ByteUtil.toHexString(data) of the entire input, allocating/formatting a hex string proportional to input size.
**Steps:**
1. Build rskj with test jar and logging disabled per reproducer.
2. Deploy bytecode `5b6000600062108000600063010000095afa50600056` that loops calling native contract 0x01000009 with 1081344-byte input until gas (6800000) runs out.
3. Run VM step loop; observe ~70s (author) / ~23s (assumed target) execution.
4. Replace hex encoding with empty string and observe runtime drop to ~4.4s, confirming cause.
**How found:** Author experimented with input sizes to find the slowest feasible payload (~1081344 bytes) and traced the slowdown to the hex-string construction in the exception path by patching it out and re-measuring.
**Exploitation:** Attacker submits a transaction whose contract repeatedly invokes a native contract with a ~1MB invalid input in an infinite loop, forcing nodes to spend tens of seconds constructing error strings per block, stalling the network.
**Insight:** When auditing EVM/native-contract error paths, check whether exception messages serialize the full calldata (hex encoding, toString) — cost scales with attacker-controlled input size and is charged outside normal gas accounting.
