-
Notifications
You must be signed in to change notification settings - Fork 1
/
weth_asm.sol
160 lines (126 loc) · 5.22 KB
/
weth_asm.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
pragma solidity 0.8.7;
contract test {
string public name = "Wrapped Ether";
string public symbol = "WETH";
uint8 public decimals = 18;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
event Deposit(address indexed dst, uint wad);
event Withdrawal(address indexed src, uint wad);
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
fallback() external payable {
deposit();
}
function deposit() public payable {
assembly {
mstore(0x0, origin()) //msg.sender
mstore(0x20, 3) //slot3: balanceOf
let hash := keccak256(0x0, 64) //from 0, for 2 bytes
let new_bal := add(callvalue(), sload(hash))
sstore(hash, new_bal)
}
}
function withdraw(uint wad) public {
assembly {
// load balanceOf key
mstore(0x0, origin()) //msg.sender
mstore(0x20, 3) //slot3: balanceOf
let hash := keccak256(0x0, 64) //from 0, for 2 bytes
// load current balance and wad
let bal := sload(hash)
let val := calldataload(4)
//require(balanceOf[msg.sender] >= wad);
if lt(bal, val) { revert(0,0) }
//balanceOf[msg.sender] -= wad;
sstore(hash, sub(bal, val))
let ret := call (22000,
origin(),
val,
0, // input
0x0, // input size = 4 bytes
0, // output stored at input location, save space
0x0 // output size = 0 bytes
)
}
}
function totalSupply() public view returns (uint) {
assembly {
let bal := selfbalance()
mstore(0x20, bal)
return(0x20, 32)
}
}
function approve(address guy, uint wad) public returns (bool) {
assembly {
let spender := calldataload(4)
let val := calldataload(36)
mstore(0x0, origin()) //msg.sender
mstore(0x20, 4) //slot4: allowance
let hash_first_level := keccak256(0x0, 64) //from 0, for 2 bytes
mstore(0x0, spender)
mstore(0x20, hash_first_level)
let hash_sec := keccak256(0x0, 64)
sstore(hash_sec, val)
mstore(0x0, 1)
return(0x0, 1)
}
}
function transfer(address dst, uint wad) public returns (bool) {
assembly {
let receiver := calldataload(4)
let val := calldataload(36)
// balanceOf[src]
mstore(0x0, origin()) //msg.sender
mstore(0x20, 3) //slot3: balanceOf
let hash_sender := keccak256(0x0, 64) //from 0, for 2 bytes
let bal_sender := sload(hash_sender)
// balance < wad ?
if lt(bal_sender, val) { revert(0,0) }
sstore(hash_sender, sub(bal_sender, val))
mstore(0x0, receiver)
mstore(0x20, 3) //slot3: balanceOf
let hash_receiver := keccak256(0x0, 64) //from 0, for 2 bytes
sstore(hash_receiver, add(sload(hash_receiver), val))
mstore(0x0, 1)
return(0x0, 1)
}
}
function transferFrom(address src, address dst, uint wad) public returns(bool) {
assembly {
let sender := calldataload(4)
let receiver := calldataload(36)
let val := calldataload(68)
// balanceOf[src]
mstore(0x0, sender) //msg.sender
mstore(0x20, 3) //slot3: balanceOf
let hash_sender := keccak256(0x0, 64) //from 0, for 2 bytes
let bal_sender := sload(hash_sender)
// balance < wad ?
if lt(bal_sender, val) { revert(0,0) }
// src != msg.sender ?
if lt(eq(sender, origin()), 1) {
mstore(0x0, origin()) //msg.sender
mstore(0x20, 4) //slot4: allowance
let hash_first_level := keccak256(0x0, 64) //from 0, for 2 bytes
mstore(0x0, sender)
mstore(0x20, hash_first_level)
let hash_sec := keccak256(0x0, 64)
// allowance[src][msg.sender] != type(uint).max ?
if lt(sload(hash_sec), not(0x0)) {
// allowance[src][msg.sender] < wad ?
if lt(sload(hash_sec), val) { revert(0,0) }
// allowance[src][msg.sender] -= val
sstore(hash_sec, sub(sload(hash_sec), val))
}
}
sstore(hash_sender, sub(bal_sender, val))
mstore(0x0, receiver)
mstore(0x20, 3) //slot3: balanceOf
let hash_receiver := keccak256(0x0, 64) //from 0, for 2 bytes
sstore(hash_receiver, add(sload(hash_receiver), val))
mstore(0x0, 1)
return(0x0, 1)
}
}
}