-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathstdlib.lll
More file actions
169 lines (141 loc) · 7.23 KB
/
stdlib.lll
File metadata and controls
169 lines (141 loc) · 7.23 KB
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
161
162
163
164
165
166
167
168
169
;;; ---------------------------------------------------------------------------
;;; @title A standard library of LLL macros.
;;; @author Daniel Ellison <daniel@syrinx.net>
;;;
;;; Copyright 2016 Daniel Ellison
;;;
;;; Licensed under the Apache License, Version 2.0 (the "License");
;;; you may not use this file except in compliance with the License.
;;; You may obtain a copy of the License at
;;;
;;; http://www.apache.org/licenses/LICENSE-2.0
;;;
;;; Unless required by applicable law or agreed to in writing, software
;;; distributed under the License is distributed on an "AS IS" BASIS,
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;;; See the License for the specific language governing permissions and
;;; limitations under the License.
(seq
;; --------------------------------------------------------------------------
;; Constant definitions.
;; Booleans.
(def 'true 1)
(def 'false 0)
;; Miscellaneous.
(def 'stdlib-version "0.1.2") ; Contracts can abort on version mismatch.
(def 'invalid-location 0x02) ; Jumping here causes an EVM panic.
(def 'hold-back 1000) ; Amount of gas to hold back on <call>.
;; Memory layout.
(def 'scratch-one 0x0000) ; Scratch space.
(def 'scratch-two 0x0020) ; More scratch space.
(def 'return-code 0x0040) ; Boolean returned to calling contract.
(def 'return-data 0x0060) ; Data returned to calling contract.
(def 'call-result 0x0160) ; Data returned from called contract.
(def 'call-data 0x0260) ; Data provided to called contract.
(def 'user-memory 0x02c4) ; Library user memory start.
;; --------------------------------------------------------------------------
;; @notice Shifts the rightmost 4 bytes of a 32-byte number left by 28 bytes.
;; @dev 0x14ab90388092664827928d90384c73d82c5bf21abb61dd7d4971fc65f4851dfb
;; 0xf4851dfb00000000000000000000000000000000000000000000000000000000
;; @param input A 32-byte number.
(def 'shift-left (input)
(mul input (exp 2 224)))
;; --------------------------------------------------------------------------
;; @notice Shifts the leftmost 4 bytes of a 32-byte number right by 28 bytes.
;; @dev 0x14ab90388092664827928d90384c73d82c5bf21abb61dd7d4971fc65f4851dfb
;; 0x0000000000000000000000000000000000000000000000000000000014ab9038
;; @param input A 32-byte number.
(def 'shift-right (input)
(div input (exp 2 224)))
;; --------------------------------------------------------------------------
;; @notice Determines whether the supplied function ID matches a known
;; function hash and executes <code-body> if so.
;; @dev The function ID is in the leftmost four bytes of the call data.
;; @param function-hash The four-byte hash of a known function signature.
;; @param code-body The code to run in the case of a match.
(def 'function (function-hash code-body)
(when (= (shift-right (calldataload 0x00)) function-hash)
code-body))
;; --------------------------------------------------------------------------
;; @notice Calls another contract with no paramaters.
;; @dev Sends all but <hold-back> gas to called contract. Assumes no ether to
;; be sent to called contract.
;; @param contract-address The address of the contract to call.
;; @param function-hash Short hash of the function to call.
;; @param return-size The parameter return size of the called function.
(def 'call0 (contract-address function-hash return-size)
(seq
(mstore call-data (shift-left function-hash))
(call (- (gas) hold-back) 0 contract-address
call-data 4 return-data return-size)))
;; --------------------------------------------------------------------------
;; @notice Calls another contract with one paramater.
;; @dev Sends all but <hold-back> gas to called contract. Assumes no ether to
;; be sent to called contract. Assumes 32-byte parameters.
;; @param contract-address The address of the contract to call.
;; @param function-hash Short hash of the function to call.
;; @param param1 The first (and only) parameter to the function call.
;; @param return-size The parameter return size of the called function.
(def 'call1 (contract-address function-hash param1 return-size)
(seq
(mstore (+ call-data 0x00) (shift-left function-hash))
(mstore (+ call-data 0x04) param1)
(call (- (gas) hold-back) 0 contract-address
call-data 36 return-data return-size)))
;; --------------------------------------------------------------------------
;; @notice Calls another contract with two paramaters.
;; @dev Sends all but <hold-back> gas to called contract. Assumes no ether to
;; be sent to called contract. Assumes 32-byte parameters.
;; @param contract-address The address of the contract to call.
;; @param function-hash Short hash of the function to call.
;; @param param1 The first parameter to the function call.
;; @param param2 The second parameter to the function call.
;; @param return-size The parameter return size of the called function.
(def 'call2 (contract-address function-hash param1 param2 return-size)
(seq
(mstore (+ call-data 0x00) (shift-left function-hash))
(mstore (+ call-data 0x04) param1)
(mstore (+ call-data 0x24) param2)
(call (- (gas) hold-back) 0 contract-address
call-data 68 return-data return-size)))
;; --------------------------------------------------------------------------
;; @notice Calls another contract with three paramaters.
;; @dev Sends all but <hold-back> gas to called contract. Assumes no ether to
;; be sent to called contract. Assumes 32-byte parameters.
;; @param contract-address The address of the contract to call.
;; @param function-hash Short hash of the function to call.
;; @param param1 The first parameter to the function call.
;; @param param2 The second parameter to the function call.
;; @param param3 The third parameter to the function call.
;; @param return-size The parameter return size of the called function.
(def 'call3 (contract-address function-hash param1 param2 param3 return-size)
(seq
(mstore (+ call-data 0x00) (shift-left function-hash))
(mstore (+ call-data 0x04) param1)
(mstore (+ call-data 0x24) param2)
(mstore (+ call-data 0x44) param3)
(call (- (gas) hold-back) 0 contract-address
call-data 100 return-data return-size)))
;; --------------------------------------------------------------------------
;; @notice Increments the value @loc by 1.
;; @param loc The memory location to increment.
(def '++ (loc)
(mstore loc (+ @loc 1)))
;; --------------------------------------------------------------------------
;; @notice Decrements the value @loc by 1.
;; @param loc The memory location to decrement.
(def '-- (loc)
(mstore loc (- @loc 1)))
;; --------------------------------------------------------------------------
;; @notice Returns the smaller of two numbers.
;; @param a First number.
;; @param b Second number.
(def 'min (a b)
(if (< a b) a b))
;; --------------------------------------------------------------------------
;; @notice Returns the larger of two numbers.
;; @param a First number.
;; @param b Second number.
(def 'max (a b)
(if (> a b) a b))
)