├── .editorconfig
├── .gitconfig
├── .gitignore
├── approximate_mpmath.ipynb
├── approximation_float.ipynb
├── evaluation.ipynb
├── foundry copy.toml
├── foundry.toml
├── simulation.ipynb
└── src
├── FixedPointMathLib.sol
└── test
├── FixedPointMathLib.t.sol
└── console.sol
/.editorconfig:
--------------------------------------------------------------------------------
1 | # See
2 | root = true
3 |
4 | [*]
5 | end_of_line = lf
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 | indent_style = space
10 | indent_size = 4
11 |
12 | [*.{yml,yaml}]
13 | indent_size = 2
14 |
--------------------------------------------------------------------------------
/.gitconfig:
--------------------------------------------------------------------------------
1 | # git config --local include.path ../.gitconfig
2 |
3 | [filter "jupyternotebook"]
4 | clean = jupyter nbconvert --clear-output %f
5 | required
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | cache
2 | out
--------------------------------------------------------------------------------
/evaluation.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "35dfaedf-9233-4ac3-9861-d1b1f92f56ef",
6 | "metadata": {},
7 | "source": [
8 | "## Horner, Clenshaw, Knuth"
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": 4,
14 | "id": "955423fb-cdbd-45fd-818c-79dc3309cb47",
15 | "metadata": {},
16 | "outputs": [],
17 | "source": [
18 | "def poly_cond(start, stop, coefficients):\n",
19 | " x = np.linspace(start, stop, 1000)\n",
20 | " cond = evaluate(np.abs(coefficients), np.abs(x)) / np.abs(evaluate(coefficients, x))\n",
21 | " plt.plot(x, cond)\n",
22 | " return np.max(cond)"
23 | ]
24 | },
25 | {
26 | "cell_type": "code",
27 | "execution_count": 5,
28 | "id": "b74fd3cd-6af7-4123-b7c9-ee64828707df",
29 | "metadata": {},
30 | "outputs": [
31 | {
32 | "ename": "SyntaxError",
33 | "evalue": "invalid syntax (52742565.py, line 3)",
34 | "output_type": "error",
35 | "traceback": [
36 | "\u001b[0;36m Input \u001b[0;32mIn [5]\u001b[0;36m\u001b[0m\n\u001b[0;31m y = evaluate(coefficients, x)a\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
37 | ]
38 | }
39 | ],
40 | "source": [
41 | "def shift_coefficients(coefficients, shift):\n",
42 | " x = np.linspace(0, 1, coefficients.shape[0])\n",
43 | " y = evaluate(coefficients, x)a\n",
44 | " x -= shift\n",
45 | " c = interpolate_poly(x, y)\n",
46 | " return c"
47 | ]
48 | },
49 | {
50 | "cell_type": "code",
51 | "execution_count": 3,
52 | "id": "03f0898c-cc00-4344-a830-fed10b193801",
53 | "metadata": {},
54 | "outputs": [
55 | {
56 | "ename": "NameError",
57 | "evalue": "name 'np' is not defined",
58 | "output_type": "error",
59 | "traceback": [
60 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
61 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
62 | "Input \u001b[0;32mIn [3]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m c \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241m.\u001b[39marray([ \u001b[38;5;241m1.\u001b[39m , \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1.94817029\u001b[39m, \u001b[38;5;241m1.86036663\u001b[39m])\n",
63 | "\u001b[0;31mNameError\u001b[0m: name 'np' is not defined"
64 | ]
65 | }
66 | ],
67 | "source": [
68 | "c = np.array([ 1. , -1.94817029, 1.86036663])"
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "execution_count": null,
74 | "id": "67bf5fd3-201b-4dde-8b33-6b4a15f35463",
75 | "metadata": {},
76 | "outputs": [],
77 | "source": []
78 | }
79 | ],
80 | "metadata": {
81 | "kernelspec": {
82 | "display_name": "Python 3 (ipykernel)",
83 | "language": "python",
84 | "name": "python3"
85 | },
86 | "language_info": {
87 | "codemirror_mode": {
88 | "name": "ipython",
89 | "version": 3
90 | },
91 | "file_extension": ".py",
92 | "mimetype": "text/x-python",
93 | "name": "python",
94 | "nbconvert_exporter": "python",
95 | "pygments_lexer": "ipython3",
96 | "version": "3.9.10"
97 | }
98 | },
99 | "nbformat": 4,
100 | "nbformat_minor": 5
101 | }
102 |
--------------------------------------------------------------------------------
/foundry copy.toml:
--------------------------------------------------------------------------------
1 | [default]
2 | optimizer_runs = 1000000
3 | bytecode_hash = "none"
4 |
5 | [intense]
6 | fuzz_runs = 10000
7 |
--------------------------------------------------------------------------------
/foundry.toml:
--------------------------------------------------------------------------------
1 | [default]
2 | src = 'src'
3 | out = 'out'
4 | libs = ['lib']
5 | remappings = ['ds-test/=lib/ds-test/src/']
6 |
7 | # See more config options https://github.com/gakonst/foundry/tree/master/config
--------------------------------------------------------------------------------
/simulation.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Simulation"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {
13 | "tags": []
14 | },
15 | "source": [
16 | "## Prelude"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": 699,
22 | "metadata": {},
23 | "outputs": [
24 | {
25 | "name": "stdout",
26 | "output_type": "stream",
27 | "text": [
28 | "\u001b[33mDEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621\u001b[0m\u001b[33m\n",
29 | "\u001b[0mRequirement already satisfied: matplotlib in /opt/homebrew/lib/python3.9/site-packages (3.5.1)\n",
30 | "Requirement already satisfied: numpy in /opt/homebrew/lib/python3.9/site-packages (1.22.2)\n",
31 | "Requirement already satisfied: mpmath in /opt/homebrew/lib/python3.9/site-packages (1.2.1)\n",
32 | "Requirement already satisfied: watermark in /opt/homebrew/lib/python3.9/site-packages (2.3.0)\n",
33 | "Requirement already satisfied: packaging>=20.0 in /opt/homebrew/lib/python3.9/site-packages (from matplotlib) (21.3)\n",
34 | "Requirement already satisfied: kiwisolver>=1.0.1 in /opt/homebrew/lib/python3.9/site-packages (from matplotlib) (1.3.2)\n",
35 | "Requirement already satisfied: pyparsing>=2.2.1 in /opt/homebrew/lib/python3.9/site-packages (from matplotlib) (3.0.7)\n",
36 | "Requirement already satisfied: pillow>=6.2.0 in /opt/homebrew/lib/python3.9/site-packages (from matplotlib) (9.0.1)\n",
37 | "Requirement already satisfied: python-dateutil>=2.7 in /opt/homebrew/lib/python3.9/site-packages (from matplotlib) (2.8.2)\n",
38 | "Requirement already satisfied: fonttools>=4.22.0 in /opt/homebrew/lib/python3.9/site-packages (from matplotlib) (4.29.1)\n",
39 | "Requirement already satisfied: cycler>=0.10 in /opt/homebrew/lib/python3.9/site-packages (from matplotlib) (0.11.0)\n",
40 | "Requirement already satisfied: ipython in /opt/homebrew/lib/python3.9/site-packages (from watermark) (8.1.1)\n",
41 | "Requirement already satisfied: six>=1.5 in /opt/homebrew/lib/python3.9/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n",
42 | "Requirement already satisfied: stack-data in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (0.2.0)\n",
43 | "Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (3.0.28)\n",
44 | "Requirement already satisfied: pexpect>4.3 in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (4.8.0)\n",
45 | "Requirement already satisfied: matplotlib-inline in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (0.1.3)\n",
46 | "Requirement already satisfied: traitlets>=5 in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (5.1.1)\n",
47 | "Requirement already satisfied: setuptools>=18.5 in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (60.9.3)\n",
48 | "Requirement already satisfied: pygments>=2.4.0 in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (2.11.2)\n",
49 | "Requirement already satisfied: backcall in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (0.2.0)\n",
50 | "Requirement already satisfied: pickleshare in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (0.7.5)\n",
51 | "Requirement already satisfied: decorator in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (5.1.1)\n",
52 | "Requirement already satisfied: jedi>=0.16 in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (0.18.1)\n",
53 | "Requirement already satisfied: appnope in /opt/homebrew/lib/python3.9/site-packages (from ipython->watermark) (0.1.2)\n",
54 | "Requirement already satisfied: parso<0.9.0,>=0.8.0 in /opt/homebrew/lib/python3.9/site-packages (from jedi>=0.16->ipython->watermark) (0.8.3)\n",
55 | "Requirement already satisfied: ptyprocess>=0.5 in /opt/homebrew/lib/python3.9/site-packages (from pexpect>4.3->ipython->watermark) (0.7.0)\n",
56 | "Requirement already satisfied: wcwidth in /opt/homebrew/lib/python3.9/site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython->watermark) (0.2.5)\n",
57 | "Requirement already satisfied: pure-eval in /opt/homebrew/lib/python3.9/site-packages (from stack-data->ipython->watermark) (0.2.2)\n",
58 | "Requirement already satisfied: asttokens in /opt/homebrew/lib/python3.9/site-packages (from stack-data->ipython->watermark) (2.0.5)\n",
59 | "Requirement already satisfied: executing in /opt/homebrew/lib/python3.9/site-packages (from stack-data->ipython->watermark) (0.8.3)\n",
60 | "\u001b[33mDEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621\u001b[0m\u001b[33m\n",
61 | "\u001b[0m"
62 | ]
63 | }
64 | ],
65 | "source": [
66 | "!pip install matplotlib numpy mpmath watermark"
67 | ]
68 | },
69 | {
70 | "cell_type": "code",
71 | "execution_count": 700,
72 | "metadata": {},
73 | "outputs": [],
74 | "source": [
75 | "%matplotlib inline\n",
76 | "\n",
77 | "import matplotlib\n",
78 | "import numpy as np\n",
79 | "from mpmath import mp\n",
80 | "import matplotlib.pyplot as plt\n",
81 | "import math\n",
82 | "import warnings\n",
83 | "from ipywidgets import interact, interactive, fixed, interact_manual"
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": 701,
89 | "metadata": {},
90 | "outputs": [],
91 | "source": [
92 | "plt.rcParams['figure.dpi'] = 90\n",
93 | "plt.rcParams['figure.figsize'] = [12.0, 8.0]\n",
94 | "plt.rcParams['text.usetex'] = False"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": null,
100 | "metadata": {},
101 | "outputs": [],
102 | "source": []
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": 702,
107 | "metadata": {},
108 | "outputs": [
109 | {
110 | "name": "stdout",
111 | "output_type": "stream",
112 | "text": [
113 | "Python implementation: CPython\n",
114 | "Python version : 3.9.10\n",
115 | "IPython version : 8.1.0\n",
116 | "\n",
117 | "Compiler : Clang 13.0.0 (clang-1300.0.29.3)\n",
118 | "OS : Darwin\n",
119 | "Release : 21.3.0\n",
120 | "Machine : arm64\n",
121 | "Processor : arm\n",
122 | "CPU cores : 10\n",
123 | "Architecture: 64bit\n",
124 | "\n",
125 | "numpy : 1.22.2\n",
126 | "matplotlib: 3.5.1\n",
127 | "\n"
128 | ]
129 | }
130 | ],
131 | "source": [
132 | "import watermark.watermark as watermark\n",
133 | "print(watermark(machine=True, iso8601=True, python=True, iversions=True, globals_=globals()))"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": 703,
139 | "metadata": {},
140 | "outputs": [],
141 | "source": [
142 | "def intrange(bot, top, num = 100):\n",
143 | " bot = int(bot)\n",
144 | " top = int(top)\n",
145 | " x = np.linspace(bot, top, num = num)\n",
146 | " x = [max(min(int(x), top), bot) for x in x]\n",
147 | " return x"
148 | ]
149 | },
150 | {
151 | "cell_type": "markdown",
152 | "metadata": {},
153 | "source": [
154 | "## EVM primitives"
155 | ]
156 | },
157 | {
158 | "cell_type": "code",
159 | "execution_count": 704,
160 | "metadata": {},
161 | "outputs": [],
162 | "source": [
163 | "BASE = 2**256\n",
164 | "SIGN = BASE // 2"
165 | ]
166 | },
167 | {
168 | "cell_type": "code",
169 | "execution_count": 705,
170 | "metadata": {},
171 | "outputs": [],
172 | "source": [
173 | "def _valid(a):\n",
174 | " assert type(a) is int\n",
175 | " assert a >= 0\n",
176 | " assert a < BASE\n",
177 | "\n",
178 | "def _abs(a):\n",
179 | " _valid(a)\n",
180 | " if a > SIGN:\n",
181 | " a = BASE - a\n",
182 | " assert a >= 0 and a < SIGN\n",
183 | " return a\n",
184 | "\n",
185 | "def bnot(a):\n",
186 | " _valid(a)\n",
187 | " return a ^ (BASE - 1)\n",
188 | "\n",
189 | "def bor(a, b):\n",
190 | " _valid(a)\n",
191 | " _valid(b)\n",
192 | " return a | b\n",
193 | "\n",
194 | "def lt(a, b):\n",
195 | " _valid(a)\n",
196 | " _valid(b)\n",
197 | " return 1 if a < b else 0\n",
198 | "\n",
199 | "def shl(a, b):\n",
200 | " _valid(a)\n",
201 | " _valid(b)\n",
202 | " return (b << a) % BASE\n",
203 | "\n",
204 | "def shr(a, b):\n",
205 | " _valid(a)\n",
206 | " _valid(b)\n",
207 | " return (b >> a) % BASE\n",
208 | "\n",
209 | "def sar(a, b):\n",
210 | " _valid(a)\n",
211 | " _valid(b)\n",
212 | " if b >= SIGN:\n",
213 | " b = BASE - b\n",
214 | " b >>= a\n",
215 | " b = BASE - max(b, 1)\n",
216 | " return b\n",
217 | " else:\n",
218 | " return (b >> a) % BASE\n",
219 | "\n",
220 | "def add(a, b):\n",
221 | " _valid(a)\n",
222 | " _valid(b)\n",
223 | " return (a + b) % BASE\n",
224 | "\n",
225 | "def sub(a, b):\n",
226 | " _valid(a)\n",
227 | " _valid(b)\n",
228 | " return (a - b) % BASE\n",
229 | "\n",
230 | "def mul(a, b):\n",
231 | " _valid(a)\n",
232 | " _valid(b)\n",
233 | " return (a * b) % BASE\n",
234 | "\n",
235 | "def div(a, b):\n",
236 | " _valid(a)\n",
237 | " _valid(b)\n",
238 | " return a // b\n",
239 | "\n",
240 | "def sdiv(a, b):\n",
241 | " _valid(a)\n",
242 | " _valid(b)\n",
243 | " r = _abs(a) // _abs(b)\n",
244 | " assert r >= 0 and r < SIGN\n",
245 | " if r > 0 and ((a >= SIGN) ^ (b >= SIGN)):\n",
246 | " r = BASE - r\n",
247 | " assert r >= 0 and r < BASE \n",
248 | " return r\n",
249 | "\n",
250 | "def mod(a, b):\n",
251 | " _valid(a)\n",
252 | " _valid(b)\n",
253 | " return (a % b) % BASE\n",
254 | "\n",
255 | "def smod(a, b):\n",
256 | " _valid(a)\n",
257 | " _valid(b)\n",
258 | " if b >= SIGN:\n",
259 | " b = BASE - b\n",
260 | " if a < SIGN:\n",
261 | " return (a % b) % BASE\n",
262 | " else:\n",
263 | " a = BASE - a\n",
264 | " return BASE - ((a % b) % BASE)\n",
265 | "\n",
266 | "def mulmod(a, b, c):\n",
267 | " _valid(a)\n",
268 | " _valid(b)\n",
269 | " _valid(c)\n",
270 | " return ((a * b) % c) % BASE"
271 | ]
272 | },
273 | {
274 | "cell_type": "code",
275 | "execution_count": null,
276 | "metadata": {},
277 | "outputs": [],
278 | "source": []
279 | },
280 | {
281 | "cell_type": "code",
282 | "execution_count": null,
283 | "metadata": {},
284 | "outputs": [],
285 | "source": []
286 | },
287 | {
288 | "cell_type": "markdown",
289 | "metadata": {},
290 | "source": [
291 | "## Ground truth"
292 | ]
293 | },
294 | {
295 | "cell_type": "code",
296 | "execution_count": 706,
297 | "metadata": {},
298 | "outputs": [],
299 | "source": [
300 | "PRECISION = 1024 # Bits\n",
301 | "mp.prec = PRECISION"
302 | ]
303 | },
304 | {
305 | "cell_type": "code",
306 | "execution_count": 707,
307 | "metadata": {},
308 | "outputs": [],
309 | "source": [
310 | "FIX_1 = 10**18\n",
311 | "MP_FIX_1 = mp.mpf(FIX_1)"
312 | ]
313 | },
314 | {
315 | "cell_type": "code",
316 | "execution_count": 708,
317 | "metadata": {},
318 | "outputs": [],
319 | "source": [
320 | "def fix_to_mp(x):\n",
321 | " _valid(x)\n",
322 | " if x < 2**255:\n",
323 | " return mp.mpf(x) / MP_FIX_1\n",
324 | " else:\n",
325 | " x = 2**256 - x\n",
326 | " return -mp.mpf(x) / MP_FIX_1"
327 | ]
328 | },
329 | {
330 | "cell_type": "code",
331 | "execution_count": 709,
332 | "metadata": {},
333 | "outputs": [],
334 | "source": [
335 | "def fix_to_f(x):\n",
336 | " return float(fix_to_mp(x))"
337 | ]
338 | },
339 | {
340 | "cell_type": "code",
341 | "execution_count": 710,
342 | "metadata": {},
343 | "outputs": [],
344 | "source": [
345 | "def mp_to_fix(x):\n",
346 | " # Closest approximation, clamping to MIN and MAX representable values, NaN maps to positive infinite\n",
347 | " if mp.isnan(x):\n",
348 | " return SIGN - 1\n",
349 | " if x >= 0:\n",
350 | " if x >= SIGN:\n",
351 | " return SIGN - 1\n",
352 | " x = int(mp.nint(x * MP_FIX_1))\n",
353 | " else:\n",
354 | " if -x > SIGN:\n",
355 | " return SIGN\n",
356 | " x = int(mp.nint(-x * MP_FIX_1))\n",
357 | " if x > 0:\n",
358 | " x = 2**256 - x\n",
359 | " _valid(x)\n",
360 | " return x"
361 | ]
362 | },
363 | {
364 | "cell_type": "code",
365 | "execution_count": 711,
366 | "metadata": {},
367 | "outputs": [],
368 | "source": [
369 | "def fmul(a, b):\n",
370 | " return bf_to_fix(fix_to_mp(a) * fix_to_mp(b))"
371 | ]
372 | },
373 | {
374 | "cell_type": "code",
375 | "execution_count": 712,
376 | "metadata": {},
377 | "outputs": [],
378 | "source": [
379 | "def mp_log1(x):\n",
380 | " return mp_to_fix(mp.log(fix_to_mp(x)))"
381 | ]
382 | },
383 | {
384 | "cell_type": "code",
385 | "execution_count": 713,
386 | "metadata": {},
387 | "outputs": [],
388 | "source": [
389 | "def mp_ln(x):\n",
390 | " return mp_to_fix(mp.log(fix_to_mp(x)))"
391 | ]
392 | },
393 | {
394 | "cell_type": "code",
395 | "execution_count": 714,
396 | "metadata": {},
397 | "outputs": [],
398 | "source": [
399 | "def mp_exp(x):\n",
400 | " return mp_to_fix(mp.exp(fix_to_mp(x)))"
401 | ]
402 | },
403 | {
404 | "cell_type": "code",
405 | "execution_count": 715,
406 | "metadata": {},
407 | "outputs": [],
408 | "source": [
409 | "assert fix_to_f(FIX_1) == 1.0"
410 | ]
411 | },
412 | {
413 | "cell_type": "markdown",
414 | "metadata": {},
415 | "source": [
416 | "## Cheby generator"
417 | ]
418 | },
419 | {
420 | "cell_type": "code",
421 | "execution_count": 716,
422 | "metadata": {},
423 | "outputs": [],
424 | "source": [
425 | "def chebyfun(f, domain, degree=11):\n",
426 | " start, end = domain\n",
427 | " start = mp.mpf(start)\n",
428 | " end = mp.mpf(end)\n",
429 | " mid = start + (end - start) / 2\n",
430 | " \n",
431 | " # To make the polynomial evaluate nicely, we center x around zero using an offset CENTER\n",
432 | " # Alternatively we could use Clenshaw's algorithm\n",
433 | " # TODO: Centering helps a lot, what about scaling?\n",
434 | " coeffs = mp.chebyfit(lambda x: f(x + mid), [start - mid, end - mid], degree)\n",
435 | " coeffs = [mp_to_fix(x) for x in coeffs]\n",
436 | " mid = mp_to_fix(mid)\n",
437 | " \n",
438 | " # Solidity function\n",
439 | " def func(x):\n",
440 | " nonlocal mid, coeffs\n",
441 | " x = sub(x, mid)\n",
442 | " r = coeffs[0]\n",
443 | " for coeff in coeffs[1:]:\n",
444 | " # r = (r * x / 1e18) + coeff\n",
445 | " r = mul(r, x)\n",
446 | " r = sdiv(r, FIX_1)\n",
447 | " r = add(r, coeff)\n",
448 | " return r\n",
449 | " \n",
450 | " # Plot error\n",
451 | " x = intrange(mp_to_fix(start), mp_to_fix(end), num = 10000)\n",
452 | " xr = np.array([fix_to_f(x) for x in x])\n",
453 | " y = np.array([mp_to_fix(f(fix_to_mp(x))) for x in x], dtype='object')\n",
454 | " yr = np.array([fix_to_f(y) for y in y])\n",
455 | " fy = np.array([func(x) for x in x], dtype='object')\n",
456 | " fyr = np.array([fix_to_f(y) for y in fy])\n",
457 | " plt.title('Error over domain')\n",
458 | " plt.xlabel(\"$x$\")\n",
459 | " plt.ylabel(\"$f(x) - r$\")\n",
460 | " plt.plot(xr, (fyr - yr).astype(float))\n",
461 | " plt.axhline(-0.5 / FIX_1, color='red')\n",
462 | " plt.axhline(+0.5 / FIX_1, color='red')\n",
463 | " error_fix = max(abs(fy - y))\n",
464 | " error_bits = max(np.log2(abs(fy - y).astype(float)))\n",
465 | " \n",
466 | " # Print Solidity\n",
467 | " print('// Chebyshev approximation on ({:.4g}, {:.4g}) deg {}.'.format(float(start), float(end), degree))\n",
468 | " print('// Max observed error {:.2g}, last {:.2g} bits.'.format(fix_to_f(error_fix), error_bits))\n",
469 | " if mid < SIGN:\n",
470 | " print('x -= 0x{:x}; // {:.3g}'.format(mid, fix_to_f(mid)))\n",
471 | " else:\n",
472 | " print('x += 0x{:x}; // {:.3g}'.format(BASE - mid, fix_to_f(mid)))\n",
473 | " if coeffs[0] < SIGN:\n",
474 | " print('int256 r = 0x{:x}; // {:.3g}'.format(coeffs[0], fix_to_f(coeffs[0])))\n",
475 | " else:\n",
476 | " print('int256 r = -0x{:x}; // {:.3g}'.format(BASE - coeffs[0], fix_to_f(coeffs[0])))\n",
477 | " for x in coeffs:\n",
478 | " if x < SIGN:\n",
479 | " print('r = ((r * x) / FIX_1) + 0x{:x}; // {:.3g}'.format(x, fix_to_f(x)))\n",
480 | " else:\n",
481 | " print('r = ((r * x) / FIX_1) - 0x{:x}; // {:.3g}'.format(BASE - x, fix_to_f(x)))\n",
482 | "\n",
483 | " return func"
484 | ]
485 | },
486 | {
487 | "cell_type": "code",
488 | "execution_count": 717,
489 | "metadata": {},
490 | "outputs": [],
491 | "source": [
492 | "def fn_exp(x):\n",
493 | " return mp.exp(x)"
494 | ]
495 | },
496 | {
497 | "cell_type": "code",
498 | "execution_count": 718,
499 | "metadata": {},
500 | "outputs": [],
501 | "source": [
502 | "domain = (0.0, 0.125)"
503 | ]
504 | },
505 | {
506 | "cell_type": "code",
507 | "execution_count": 719,
508 | "metadata": {},
509 | "outputs": [
510 | {
511 | "data": {
512 | "application/vnd.jupyter.widget-view+json": {
513 | "model_id": "915829888f96495eb8e3154383177fb8",
514 | "version_major": 2,
515 | "version_minor": 0
516 | },
517 | "text/plain": [
518 | "interactive(children=(IntSlider(value=8, description='d', max=24, min=-8), Output()), _dom_classes=('widget-in…"
519 | ]
520 | },
521 | "metadata": {},
522 | "output_type": "display_data"
523 | },
524 | {
525 | "data": {
526 | "text/plain": [
527 | "(d)>"
528 | ]
529 | },
530 | "execution_count": 719,
531 | "metadata": {},
532 | "output_type": "execute_result"
533 | }
534 | ],
535 | "source": [
536 | "interact(lambda d:chebyfun(fn_exp, domain, degree=d), d=8)"
537 | ]
538 | },
539 | {
540 | "cell_type": "code",
541 | "execution_count": 720,
542 | "metadata": {},
543 | "outputs": [
544 | {
545 | "data": {
546 | "text/plain": [
547 | "mpf('1.0')"
548 | ]
549 | },
550 | "execution_count": 720,
551 | "metadata": {},
552 | "output_type": "execute_result"
553 | }
554 | ],
555 | "source": [
556 | "fix_to_mp(FIX_1)"
557 | ]
558 | },
559 | {
560 | "cell_type": "code",
561 | "execution_count": 721,
562 | "metadata": {},
563 | "outputs": [
564 | {
565 | "data": {
566 | "text/plain": [
567 | "115792089237316195423570985008687907853269984665640564039457084007913129639936"
568 | ]
569 | },
570 | "execution_count": 721,
571 | "metadata": {},
572 | "output_type": "execute_result"
573 | }
574 | ],
575 | "source": [
576 | "sdiv(115792089237316195423570985008687907853269484665640564039457584007913129639936, FIX_1)"
577 | ]
578 | },
579 | {
580 | "cell_type": "code",
581 | "execution_count": 722,
582 | "metadata": {},
583 | "outputs": [
584 | {
585 | "name": "stdout",
586 | "output_type": "stream",
587 | "text": [
588 | "// Chebyshev approximation on (0, 0.125) deg 11.\n",
589 | "// Max observed error 1e-18, last 0 bits.\n",
590 | "x -= 0xde0b6b3a764000; // 0.0625\n",
591 | "int256 r = 0x444e371820; // 2.93e-07\n",
592 | "r = ((r * x) / FIX_1) + 0x444e371820; // 2.93e-07\n",
593 | "r = ((r * x) / FIX_1) + 0x2ab10ff87b6; // 2.93e-06\n",
594 | "r = ((r * x) / FIX_1) + 0x1802ff4bd772; // 2.64e-05\n",
595 | "r = ((r * x) / FIX_1) + 0xc017fa590a66; // 0.000211\n",
596 | "r = ((r * x) / FIX_1) + 0x540a7d8e6d194; // 0.00148\n",
597 | "r = ((r * x) / FIX_1) + 0x1f83ef1568ed35; // 0.00887\n",
598 | "r = ((r * x) / FIX_1) + 0x9d93ab6b0c7caf; // 0.0444\n",
599 | "r = ((r * x) / FIX_1) + 0x2764eadac31f2ba; // 0.177\n",
600 | "r = ((r * x) / FIX_1) + 0x762ec090495d833; // 0.532\n",
601 | "r = ((r * x) / FIX_1) + 0xec5d812092bb066; // 1.06\n",
602 | "r = ((r * x) / FIX_1) + 0xec5d812092bb066; // 1.06\n"
603 | ]
604 | },
605 | {
606 | "name": "stderr",
607 | "output_type": "stream",
608 | "text": [
609 | "/var/folders/cb/n6k1dpbn7f1_n5m5dqv6rjvc0000gn/T/ipykernel_85508/2621324204.py:40: RuntimeWarning: divide by zero encountered in log2\n",
610 | " error_bits = max(np.log2(abs(fy - y).astype(float)))\n"
611 | ]
612 | },
613 | {
614 | "data": {
615 | "image/png": "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\n",
616 | "text/plain": [
617 | ""
618 | ]
619 | },
620 | "metadata": {
621 | "needs_background": "light"
622 | },
623 | "output_type": "display_data"
624 | }
625 | ],
626 | "source": [
627 | "my_log1 = chebyfun(fn_exp, domain, degree=11)"
628 | ]
629 | },
630 | {
631 | "cell_type": "code",
632 | "execution_count": 723,
633 | "metadata": {},
634 | "outputs": [
635 | {
636 | "name": "stdout",
637 | "output_type": "stream",
638 | "text": [
639 | "// Chebyshev approximation on (0, 0.125) deg 17.\n",
640 | "// Max observed error 1e-18, last 0 bits.\n",
641 | "x -= 0xde0b6b3a764000; // 0.0625\n",
642 | "int256 r = 0xc6c0; // 5.09e-14\n",
643 | "r = ((r * x) / FIX_1) + 0xc6c0; // 5.09e-14\n",
644 | "r = ((r * x) / FIX_1) + 0xc6c06; // 8.14e-13\n",
645 | "r = ((r * x) / FIX_1) + 0xba5171; // 1.22e-11\n",
646 | "r = ((r * x) / FIX_1) + 0xa30742f; // 1.71e-10\n",
647 | "r = ((r * x) / FIX_1) + 0x8475e66d; // 2.22e-09\n",
648 | "r = ((r * x) / FIX_1) + 0x63586cd21; // 2.67e-08\n",
649 | "r = ((r * x) / FIX_1) + 0x444ccad066; // 2.93e-07\n",
650 | "r = ((r * x) / FIX_1) + 0x2aaffec23f8; // 2.93e-06\n",
651 | "r = ((r * x) / FIX_1) + 0x1802ff4d43bb; // 2.64e-05\n",
652 | "r = ((r * x) / FIX_1) + 0xc017fa6a1dda; // 0.000211\n",
653 | "r = ((r * x) / FIX_1) + 0x540a7d8e6d0f5; // 0.00148\n",
654 | "r = ((r * x) / FIX_1) + 0x1f83ef1568e5bd; // 0.00887\n",
655 | "r = ((r * x) / FIX_1) + 0x9d93ab6b0c7caf; // 0.0444\n",
656 | "r = ((r * x) / FIX_1) + 0x2764eadac31f2bc; // 0.177\n",
657 | "r = ((r * x) / FIX_1) + 0x762ec090495d833; // 0.532\n",
658 | "r = ((r * x) / FIX_1) + 0xec5d812092bb066; // 1.06\n",
659 | "r = ((r * x) / FIX_1) + 0xec5d812092bb066; // 1.06\n"
660 | ]
661 | },
662 | {
663 | "name": "stderr",
664 | "output_type": "stream",
665 | "text": [
666 | "/var/folders/cb/n6k1dpbn7f1_n5m5dqv6rjvc0000gn/T/ipykernel_85508/2621324204.py:40: RuntimeWarning: divide by zero encountered in log2\n",
667 | " error_bits = max(np.log2(abs(fy - y).astype(float)))\n"
668 | ]
669 | },
670 | {
671 | "data": {
672 | "image/png": "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\n",
673 | "text/plain": [
674 | ""
675 | ]
676 | },
677 | "metadata": {
678 | "needs_background": "light"
679 | },
680 | "output_type": "display_data"
681 | }
682 | ],
683 | "source": [
684 | "my_exp = chebyfun(mp.exp, (0.0, 0.125), degree=17)"
685 | ]
686 | },
687 | {
688 | "cell_type": "code",
689 | "execution_count": null,
690 | "metadata": {},
691 | "outputs": [],
692 | "source": []
693 | },
694 | {
695 | "cell_type": "code",
696 | "execution_count": 724,
697 | "metadata": {},
698 | "outputs": [],
699 | "source": [
700 | "def chebyshev_nodes(domain, n):\n",
701 | " start, end = domain\n",
702 | " start = mp.mpf(start)\n",
703 | " end = mp.mpf(end)\n",
704 | " mid = (start + end) / 2\n",
705 | " amp = (end - start) / 2\n",
706 | " xs = []\n",
707 | " for i in range(n):\n",
708 | " f = mp.mpf(2 * i + 1) / mp.mpf(2 * n)\n",
709 | " xs += [mid - amp * mp.cos(mp.pi * f)]\n",
710 | " return xs"
711 | ]
712 | },
713 | {
714 | "cell_type": "code",
715 | "execution_count": 725,
716 | "metadata": {},
717 | "outputs": [],
718 | "source": [
719 | "def least_squares(A, b):\n",
720 | " U, S, V = mp.svd_r(A)\n",
721 | " for i in range(len(S)):\n",
722 | " if S[i] != 0:\n",
723 | " S[i] = mp.one / S[i]\n",
724 | " return V.T * mp.diag(S) * U.T * b"
725 | ]
726 | },
727 | {
728 | "cell_type": "code",
729 | "execution_count": 726,
730 | "metadata": {},
731 | "outputs": [],
732 | "source": [
733 | "def vandermonde(x, n):\n",
734 | " A = mp.matrix(len(x), n)\n",
735 | " for i, x in enumerate(x):\n",
736 | " r = mp.one\n",
737 | " for j in range(n):\n",
738 | " A[i, j] = r\n",
739 | " r *= x\n",
740 | " return A"
741 | ]
742 | },
743 | {
744 | "cell_type": "code",
745 | "execution_count": 727,
746 | "metadata": {},
747 | "outputs": [
748 | {
749 | "data": {
750 | "text/plain": [
751 | "['0xec5d812092bb066',\n",
752 | " '0xec5d812092bb066',\n",
753 | " '0x762ec090495d833',\n",
754 | " '0x2764eadac31f2bc',\n",
755 | " '0x9d93ab6b0c7caf',\n",
756 | " '0x1f83ef1568e5bd',\n",
757 | " '0x540a7d8e6d0f5',\n",
758 | " '0xc017fa6a1dda',\n",
759 | " '0x1802ff4d43bb',\n",
760 | " '0x2aaffec23f8',\n",
761 | " '0x444ccad066',\n",
762 | " '0x63586cd21',\n",
763 | " '0x8475e66d',\n",
764 | " '0xa30742f',\n",
765 | " '0xba5171',\n",
766 | " '0xc6c06',\n",
767 | " '0xc6c0']"
768 | ]
769 | },
770 | "execution_count": 727,
771 | "metadata": {},
772 | "output_type": "execute_result"
773 | }
774 | ],
775 | "source": [
776 | "f = lambda x: mp.exp(x + 0.0625)\n",
777 | "d = (0.0 - 0.0625, 0.125 - 0.0625)\n",
778 | "x = chebyshev_nodes(d, 17)\n",
779 | "y = mp.matrix([f(x) for x in x])\n",
780 | "c = least_squares(vandermonde(x, 17), y)\n",
781 | "[hex(mp_to_fix(c)) for c in c]"
782 | ]
783 | },
784 | {
785 | "cell_type": "code",
786 | "execution_count": 728,
787 | "metadata": {},
788 | "outputs": [],
789 | "source": [
790 | "def extrema(domain, f, c, derivative=None):\n",
791 | " # If no derivative of f is provided, produce one numerically\n",
792 | " if derivative is None:\n",
793 | " derivative = lambda x: mp.diff(f, x)\n",
794 | " \n",
795 | " # Create a derivative of the polynomial\n",
796 | " c = reversed([c for i, c in enumerate(c[0:-1:-1])])\n",
797 | " \n",
798 | " # Find extrema in the domain\n",
799 | " f = lambda x: polyval(c, x) - derivative(x)\n",
800 | " "
801 | ]
802 | },
803 | {
804 | "cell_type": "code",
805 | "execution_count": 729,
806 | "metadata": {},
807 | "outputs": [],
808 | "source": [
809 | "def remez(x, n):\n",
810 | " A = mp.matrix(len(x), n + 1)\n",
811 | " for i, x in enumerate(x):\n",
812 | " r = mp.one\n",
813 | " for j in range(n):\n",
814 | " A[i, j] = r\n",
815 | " r *= x\n",
816 | " A[i, n] = mp.one if i % 2 == 0 else -mp.one\n",
817 | " return A"
818 | ]
819 | },
820 | {
821 | "cell_type": "code",
822 | "execution_count": 730,
823 | "metadata": {},
824 | "outputs": [
825 | {
826 | "name": "stdout",
827 | "output_type": "stream",
828 | "text": [
829 | "[ 1.064494458917859429563390594642889673102196875845794886517105937190162527623104184288352002087062444916185097998146973676999146529590008869969558781261740862644423323725219259737153328509480186422719447146723913658882839342929673106434827099147177303050246944554417728929839725312684720785776136017026261039]\n",
830 | "[ 1.064494458917859429563390594642889673058638708206661182621077187627694944548695685861988047180905087922655644777457560275773875519471511126695473462269441402302811719248095048074577457344620877539438423036294088876980319546748464921955284949935366206750043877210754826871189247789411550281646876626372126051]\n",
831 | "[ 0.5322472294589297147816952973214447861877371852109614158614529618145239852511230477816272801728021393842138151567391157349025865086517863474588381859957546764036157429393020264486787014960261009671326603765063351888450741892558684401618698421040369310270487880334208761277878188066047815642755478104255637959]\n",
832 | "[ 0.1774157431529765715938984324404821293451363008884221562673741528286033602790247606113395713244427903294379088956445096432690941495974669098187620466597710916335819272159171663748525220097881359932119099643833700023678038839018264954224561343300176033191462110905524568998980126312729010890864859423679277937]\n",
833 | "[ 0.04435393578824414289847460811040169638558935999550219019600012577428252419029176129720657217111801958622629401914239016398579085708572519781968259212681188470632535726210828531782092334376872371855751965449720232486071850525929150245689523233112996021276596682506205964409221394257109250694943261398639586048]\n",
834 | "[ 0.008870787157648828579694921620170574211778441766741225886392207673862217363527027027994327029843252747852255426782551505820971911161826253563799887087396849608956870923828882195037716440322517466525915144871094371936815356809525534161493974231078616321057454477915025448362730426348494087005016215369773610703]\n",
835 | "[ 0.001478464526274804763282486341020008507843939390120061333548149389461093885524685736214496380096604811601977988234493475053708228978206173139891688916536696166237742610156804419798534217825896102783033298942173529242375558195441439643276516510394534575900561294398819742451043395797392214552645987363728813045]\n",
836 | "[ 0.0002112092180392578233260725449827385242474029286366626446912591078878299455949309852059837681589736374173695146854557474852717772167112343118603472054323138888774269998561426741390692716833238535411926250158546181315122476111039946097861300779102896863406390529719733563423955867295843427742447214566066582942]\n",
837 | "[ 0.00002640115225490722791637665270187381182223604592382667902888782965398002543642847201361788676449415392011491971055695950685089442978671412984589901237076371763921452476100471425904939188551916263744192982664613017569236824655144534977705676332511542232073928968878965707704996552535222085790509995142891228852]\n",
838 | "[ 0.000002933461361656358654761413396555577759312275864282002112377339452850687643494615219533458725343036122619926254085912656819913932269749989232553712669837832568712228608471573132602128698762537241006259927782469949018533614077108138788010969322957562286534829109240961534064587744942498486417159570005307555519]\n",
839 | "[ 0.0000002933461361656355187716101747547717051128770154261382896708750346835614928252142630546329535399550317661517908692416726191722924144275612791077871113295198244835843958003762679764043598113685212360648321041107664679937591519597167455799341725361916141019068145953593893197208893345795490823766583533874396553]\n",
840 | "[ 0.00000002666783056051358344435688355989109368905536499996616184171899096032037950805539384121847888299859255616004166046670942933554052978853498693997002846099119113811019187735235463391833593167832785787286529231426485773827825728105263085342318774631992402951418918800325983597321820739642926568376413590843380949]\n",
841 | "[ 0.000000002222319213483695566085043037615234360784726907232005495962150954283183042996818085662455512097014610571674745459463862964105445046119852599246858722416293470032911727373837150397032762185845275879002143622683663271371167652053464643611693602239230879377625753136811526898146595857841396408034711217463790307]\n",
842 | "[ 0.0000000001709476314585007848091367921242652192428219746577821311755912158880750126689089922542150719515826024828600493658254776690945397129872037528872055512419768420995947037871067204355927749876907271226395738407031090330709878232102960023408322072090373798131522425701453176651237511876447851299945561694842554428]\n",
843 | "[ 0.00000000001221052776319518549224144419398202219187214992634455672704926532638613638477163597384450511585967466381659297825311609960429337378131006722266763401889846828818995132844690298280858317289886087476687149474365319749255042546885773018490872277671925243615826435050738966319537882400060412697919258397829979339]\n",
844 | "[ 0.0000000000008140860281500512199639816991120330555884641522815948709273907803742559617303110490875172598620926764296349823804507832069197589768303095703751469392497830979132055120769091137956018190277241529773327260565140391869782551939712231476054242012793792879373709441442248825659197346342913872405712167652681914737]\n",
845 | "[ 0.00000000000005201409733527632613040307414885359809460083486869950745818992943664225980169588296119916754734262759233841579432272079176846455241866796218359986827207878227646485655673266473922933636030540845684146737967903231891274344161593831710522606046519740488174150648930764868817295177397154051253706227958096491148]\n",
846 | "[-0.000000000000000000000000000000000000001471432196441584997798426554598590794938177954058566580185820540672115016885791603144789875692927614644983060318552472207906744523033825022712613377345581026661215079249119965924364521284736843761059250523113637593653057215717725913902335878477973941937519287961456950450090807542296157914869959680613856647]\n"
847 | ]
848 | },
849 | {
850 | "data": {
851 | "text/plain": [
852 | "['0xec5d812092bb066',\n",
853 | " '0xec5d812092bb066',\n",
854 | " '0x762ec090495d833',\n",
855 | " '0x2764eadac31f2bc',\n",
856 | " '0x9d93ab6b0c7caf',\n",
857 | " '0x1f83ef1568e5bd',\n",
858 | " '0x540a7d8e6d0f5',\n",
859 | " '0xc017fa6a1dda',\n",
860 | " '0x1802ff4d43bb',\n",
861 | " '0x2aaffec23f8',\n",
862 | " '0x444ccad066',\n",
863 | " '0x63586cd21',\n",
864 | " '0x8475e66d',\n",
865 | " '0xa30742f',\n",
866 | " '0xba5160',\n",
867 | " '0xc6c06',\n",
868 | " '0xcb2e',\n",
869 | " '0x0']"
870 | ]
871 | },
872 | "execution_count": 730,
873 | "metadata": {},
874 | "output_type": "execute_result"
875 | }
876 | ],
877 | "source": [
878 | "c = least_squares(remez(x, 17), y)\n",
879 | "print(c)\n",
880 | "[hex(mp_to_fix(c)) for c in c]"
881 | ]
882 | },
883 | {
884 | "cell_type": "code",
885 | "execution_count": null,
886 | "metadata": {},
887 | "outputs": [],
888 | "source": []
889 | },
890 | {
891 | "cell_type": "code",
892 | "execution_count": null,
893 | "metadata": {},
894 | "outputs": [],
895 | "source": []
896 | },
897 | {
898 | "cell_type": "code",
899 | "execution_count": null,
900 | "metadata": {},
901 | "outputs": [],
902 | "source": []
903 | },
904 | {
905 | "cell_type": "markdown",
906 | "metadata": {},
907 | "source": [
908 | "## LibFixMath\n",
909 | "\n",
910 | "**TODO.** LibFixedMath uses signed int, not unsigned"
911 | ]
912 | },
913 | {
914 | "cell_type": "code",
915 | "execution_count": null,
916 | "metadata": {},
917 | "outputs": [],
918 | "source": [
919 | "FIXED_1 = 0x0000000000000000000000000000000080000000000000000000000000000000\n",
920 | "MANTISA_MASK = 0x7fffffffffffffffffffffffffffffff\n",
921 | "LN_MIN_VAL = 0x0000000000000000000000000000000000000000000000000000000733048c5a\n",
922 | "LN_MAX_VAL = FIXED_1\n",
923 | "EXP_MIN_VAL = BASE - 0x0000000000000000000000000000001ff0000000000000000000000000000000"
924 | ]
925 | },
926 | {
927 | "cell_type": "code",
928 | "execution_count": null,
929 | "metadata": {},
930 | "outputs": [],
931 | "source": [
932 | "def lib_toInteger(x):\n",
933 | " return div(x, FIXED_1)"
934 | ]
935 | },
936 | {
937 | "cell_type": "code",
938 | "execution_count": null,
939 | "metadata": {},
940 | "outputs": [],
941 | "source": [
942 | "def lib_toMantissa(x):\n",
943 | " if x > 0:\n",
944 | " return x & MANTISSA_MASK"
945 | ]
946 | },
947 | {
948 | "cell_type": "code",
949 | "execution_count": null,
950 | "metadata": {},
951 | "outputs": [],
952 | "source": [
953 | "def lib_mul(a, b):\n",
954 | " aI = lib_toInteger(a)\n",
955 | " aM = lib_toMantissa(a)\n",
956 | " aI = lib_toInteger(b)\n",
957 | " aM = lib_toMantissa(b)\n",
958 | " \n",
959 | " integerPart = mul(FIXED_1, mul(aI, bI))"
960 | ]
961 | },
962 | {
963 | "cell_type": "code",
964 | "execution_count": null,
965 | "metadata": {},
966 | "outputs": [],
967 | "source": [
968 | "def lib_log1(x):\n",
969 | " # Valid over range ~0.87 - 1.0\n",
970 | " r = 0\n",
971 | " y = sub(x, FIXED_1)\n",
972 | " z = y\n",
973 | " w = sdiv(mul(y, y), FIXED_1)\n",
974 | " r = add(r, sdiv(mul(z, sub(0x100000000000000000000000000000000, y)), 0x100000000000000000000000000000000))\n",
975 | " z = sdiv(mul(z, w), FIXED_1)\n",
976 | " r = add(r, sdiv(mul(z, sub(0x0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, y)), 0x200000000000000000000000000000000))\n",
977 | " z = sdiv(mul(z, w), FIXED_1)\n",
978 | " r = add(r, sdiv(mul(z, sub(0x099999999999999999999999999999999, y)), 0x300000000000000000000000000000000))\n",
979 | " z = sdiv(mul(z, w), FIXED_1)\n",
980 | " r = add(r, sdiv(mul(z, sub(0x092492492492492492492492492492492, y)), 0x400000000000000000000000000000000))\n",
981 | " z = sdiv(mul(z, w), FIXED_1)\n",
982 | " r = add(r, sdiv(mul(z, sub(0x08e38e38e38e38e38e38e38e38e38e38e, y)), 0x500000000000000000000000000000000))\n",
983 | " z = sdiv(mul(z, w), FIXED_1)\n",
984 | " r = add(r, sdiv(mul(z, sub(0x08ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b, y)), 0x600000000000000000000000000000000))\n",
985 | " z = sdiv(mul(z, w), FIXED_1)\n",
986 | " r = add(r, sdiv(mul(z, sub(0x089d89d89d89d89d89d89d89d89d89d89, y)), 0x700000000000000000000000000000000))\n",
987 | " z = sdiv(mul(z, w), FIXED_1)\n",
988 | " r = add(r, sdiv(mul(z, sub(0x088888888888888888888888888888888, y)), 0x800000000000000000000000000000000))\n",
989 | " return r"
990 | ]
991 | },
992 | {
993 | "cell_type": "code",
994 | "execution_count": null,
995 | "metadata": {},
996 | "outputs": [],
997 | "source": []
998 | },
999 | {
1000 | "cell_type": "code",
1001 | "execution_count": null,
1002 | "metadata": {},
1003 | "outputs": [],
1004 | "source": []
1005 | },
1006 | {
1007 | "cell_type": "code",
1008 | "execution_count": null,
1009 | "metadata": {},
1010 | "outputs": [],
1011 | "source": [
1012 | "t = []\n",
1013 | "def lib_ln(x, reductions='old', log='old'):\n",
1014 | " global t\n",
1015 | " _valid(x)\n",
1016 | " if x > LN_MAX_VAL:\n",
1017 | " raise \"ln: value too large\"\n",
1018 | " if x == 0 or x >= SIGN:\n",
1019 | " raise \"ln: value too small\"\n",
1020 | " if x == FIXED_1:\n",
1021 | " return 0\n",
1022 | " if x <= LN_MIN_VAL:\n",
1023 | " return EXP_MIN_VAL\n",
1024 | " \n",
1025 | " r = 0\n",
1026 | " y = 0\n",
1027 | " z = 0\n",
1028 | " w = 0\n",
1029 | " \n",
1030 | " old_values = [\n",
1031 | " 0x00000000000000000000000000000000000000000001c8464f76164760000000,\n",
1032 | " 0x00000000000000000000000000000000000000f1aaddd7742e90000000000000,\n",
1033 | " 0x00000000000000000000000000000000000afe10820813d78000000000000000,\n",
1034 | " 0x0000000000000000000000000000000002582ab704279ec00000000000000000,\n",
1035 | " 0x000000000000000000000000000000001152aaa3bf81cc000000000000000000,\n",
1036 | " 0x000000000000000000000000000000002f16ac6c59de70000000000000000000,\n",
1037 | " 0x000000000000000000000000000000004da2cbf1be5828000000000000000000,\n",
1038 | " 0x0000000000000000000000000000000063afbe7ab2082c000000000000000000,\n",
1039 | " 0x0000000000000000000000000000000070f5a893b608861e1f58934f97aea57d,\n",
1040 | " ]\n",
1041 | " new_values = [\n",
1042 | " 0x1c8464f76164681e299a0,\n",
1043 | " 0xf1aaddd7742e56d32fb9f99744,\n",
1044 | " 0xafe10820813d65dfe6a33c07f738f,\n",
1045 | " 0x2582ab704279e8efd15e0265855c47b,\n",
1046 | " 0x1152aaa3bf81cb9fdb76eae12d029572,\n",
1047 | " 0x2f16ac6c59de6f8d5d6f63c1482a7c87,\n",
1048 | " 0x4da2cbf1be5827f9eb3ad1aa9866ebb4,\n",
1049 | " 0x63afbe7ab2082ba1a0ae5e4eb1b479dd,\n",
1050 | " 0x70f5a893b608861e1f58934f97aea57d,\n",
1051 | " ]\n",
1052 | " reduction_values = old_values if reductions == 'old' else new_values\n",
1053 | " for i, v in enumerate(reduction_values):\n",
1054 | " if x <= v:\n",
1055 | " r = sub(r, 0x0000000000000000000000000000001000000000000000000000000000000000 >> i)\n",
1056 | " x = sdiv(mul(x, FIXED_1), v)\n",
1057 | " \n",
1058 | " t += [x]\n",
1059 | " if log == 'new':\n",
1060 | " return add(r, my_log1(x))\n",
1061 | " \n",
1062 | " y = sub(x, FIXED_1)\n",
1063 | " z = y\n",
1064 | " w = sdiv(mul(y, y), FIXED_1)\n",
1065 | " r = add(r, sdiv(mul(z, sub(0x100000000000000000000000000000000, y)), 0x100000000000000000000000000000000))\n",
1066 | " z = sdiv(mul(z, w), FIXED_1)\n",
1067 | " r = add(r, sdiv(mul(z, sub(0x0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, y)), 0x200000000000000000000000000000000))\n",
1068 | " z = sdiv(mul(z, w), FIXED_1)\n",
1069 | " r = add(r, sdiv(mul(z, sub(0x099999999999999999999999999999999, y)), 0x300000000000000000000000000000000))\n",
1070 | " z = sdiv(mul(z, w), FIXED_1)\n",
1071 | " r = add(r, sdiv(mul(z, sub(0x092492492492492492492492492492492, y)), 0x400000000000000000000000000000000))\n",
1072 | " z = sdiv(mul(z, w), FIXED_1)\n",
1073 | " r = add(r, sdiv(mul(z, sub(0x08e38e38e38e38e38e38e38e38e38e38e, y)), 0x500000000000000000000000000000000))\n",
1074 | " z = sdiv(mul(z, w), FIXED_1)\n",
1075 | " r = add(r, sdiv(mul(z, sub(0x08ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b, y)), 0x600000000000000000000000000000000))\n",
1076 | " z = sdiv(mul(z, w), FIXED_1)\n",
1077 | " r = add(r, sdiv(mul(z, sub(0x089d89d89d89d89d89d89d89d89d89d89, y)), 0x700000000000000000000000000000000))\n",
1078 | " z = sdiv(mul(z, w), FIXED_1)\n",
1079 | " r = add(r, sdiv(mul(z, sub(0x088888888888888888888888888888888, y)), 0x800000000000000000000000000000000))\n",
1080 | " \n",
1081 | " return r"
1082 | ]
1083 | },
1084 | {
1085 | "cell_type": "code",
1086 | "execution_count": null,
1087 | "metadata": {},
1088 | "outputs": [],
1089 | "source": [
1090 | "for i in range(-3,6):\n",
1091 | " print(2**i)\n",
1092 | " print(hex( mp_to_fix( mp.exp(-mp.mpf(2) ** (i)) )))"
1093 | ]
1094 | },
1095 | {
1096 | "cell_type": "code",
1097 | "execution_count": null,
1098 | "metadata": {},
1099 | "outputs": [],
1100 | "source": [
1101 | "def my_mul(a, b):\n",
1102 | " mm = mulmod(a, b, bnot(0))\n",
1103 | " r0 = mul(a, b)\n",
1104 | " r1 = sub(sub(mm, r0), lt(mm, r0))\n",
1105 | " r1 = add(r1, mul(sar(256, a), b))\n",
1106 | " r1 = add(r1, mul(sar(256, b), a))\n",
1107 | " r = bor(shl(129, r1), shr(127, r0))\n",
1108 | " return r"
1109 | ]
1110 | },
1111 | {
1112 | "cell_type": "code",
1113 | "execution_count": null,
1114 | "metadata": {},
1115 | "outputs": [],
1116 | "source": [
1117 | "a = 2617556668622594272776707985386330127\n",
1118 | "b = BASE - 130444458470968929913751441309200329514"
1119 | ]
1120 | },
1121 | {
1122 | "cell_type": "code",
1123 | "execution_count": null,
1124 | "metadata": {},
1125 | "outputs": [],
1126 | "source": [
1127 | "fix_to_f(a)"
1128 | ]
1129 | },
1130 | {
1131 | "cell_type": "code",
1132 | "execution_count": null,
1133 | "metadata": {},
1134 | "outputs": [],
1135 | "source": [
1136 | "fix_to_f(b)"
1137 | ]
1138 | },
1139 | {
1140 | "cell_type": "code",
1141 | "execution_count": null,
1142 | "metadata": {},
1143 | "outputs": [],
1144 | "source": [
1145 | "d = my_mul(a, b)\n",
1146 | "d"
1147 | ]
1148 | },
1149 | {
1150 | "cell_type": "code",
1151 | "execution_count": null,
1152 | "metadata": {},
1153 | "outputs": [],
1154 | "source": [
1155 | "fix_to_f(d)"
1156 | ]
1157 | },
1158 | {
1159 | "cell_type": "code",
1160 | "execution_count": null,
1161 | "metadata": {},
1162 | "outputs": [],
1163 | "source": [
1164 | "0.01538461538461533 * -0.7666836201434823"
1165 | ]
1166 | },
1167 | {
1168 | "cell_type": "code",
1169 | "execution_count": null,
1170 | "metadata": {},
1171 | "outputs": [],
1172 | "source": [
1173 | "hex(sar(256, mp_to_fix(-2)))"
1174 | ]
1175 | },
1176 | {
1177 | "cell_type": "code",
1178 | "execution_count": null,
1179 | "metadata": {},
1180 | "outputs": [],
1181 | "source": []
1182 | },
1183 | {
1184 | "cell_type": "code",
1185 | "execution_count": null,
1186 | "metadata": {},
1187 | "outputs": [],
1188 | "source": []
1189 | },
1190 | {
1191 | "cell_type": "code",
1192 | "execution_count": null,
1193 | "metadata": {},
1194 | "outputs": [],
1195 | "source": []
1196 | },
1197 | {
1198 | "cell_type": "markdown",
1199 | "metadata": {},
1200 | "source": [
1201 | "# Evaluate"
1202 | ]
1203 | },
1204 | {
1205 | "cell_type": "code",
1206 | "execution_count": null,
1207 | "metadata": {},
1208 | "outputs": [],
1209 | "source": [
1210 | "x = intrange(mp_to_fix(0.875), mp_to_fix(1.0), num = 10000)\n",
1211 | "xr = [fix_to_f(x) for x in x]"
1212 | ]
1213 | },
1214 | {
1215 | "cell_type": "code",
1216 | "execution_count": null,
1217 | "metadata": {},
1218 | "outputs": [],
1219 | "source": [
1220 | "def fix_exp(x):\n",
1221 | " return x.pow(1/(1-x))"
1222 | ]
1223 | },
1224 | {
1225 | "cell_type": "code",
1226 | "execution_count": null,
1227 | "metadata": {},
1228 | "outputs": [],
1229 | "source": [
1230 | "y = np.array([fix_exp(x) for x in x])\n",
1231 | "yr = np.array([fix_to_f(y) for y in y])"
1232 | ]
1233 | },
1234 | {
1235 | "cell_type": "markdown",
1236 | "metadata": {},
1237 | "source": [
1238 | "### Log(1 + z)"
1239 | ]
1240 | },
1241 | {
1242 | "cell_type": "code",
1243 | "execution_count": null,
1244 | "metadata": {},
1245 | "outputs": [],
1246 | "source": [
1247 | "x = intrange(mp_to_fix(0.875), mp_to_fix(1.0), num = 10000)\n",
1248 | "xr = [fix_to_f(x) for x in x]"
1249 | ]
1250 | },
1251 | {
1252 | "cell_type": "code",
1253 | "execution_count": null,
1254 | "metadata": {},
1255 | "outputs": [],
1256 | "source": [
1257 | "y = np.array([mp_log1(x) for x in x])\n",
1258 | "yr = np.array([fix_to_f(y) for y in y])"
1259 | ]
1260 | },
1261 | {
1262 | "cell_type": "code",
1263 | "execution_count": null,
1264 | "metadata": {},
1265 | "outputs": [],
1266 | "source": [
1267 | "ly = np.array([lib_log1(x) for x in x])\n",
1268 | "lyr = np.array([fix_to_f(y) for y in ly])"
1269 | ]
1270 | },
1271 | {
1272 | "cell_type": "code",
1273 | "execution_count": null,
1274 | "metadata": {},
1275 | "outputs": [],
1276 | "source": [
1277 | "my = np.array([my_log1(x) for x in x])\n",
1278 | "myr = np.array([fix_to_f(y) for y in my])"
1279 | ]
1280 | },
1281 | {
1282 | "cell_type": "code",
1283 | "execution_count": null,
1284 | "metadata": {},
1285 | "outputs": [],
1286 | "source": [
1287 | "plt.plot(xr, yr)\n",
1288 | "plt.plot(xr, lyr)\n",
1289 | "plt.plot(xr, myr)"
1290 | ]
1291 | },
1292 | {
1293 | "cell_type": "code",
1294 | "execution_count": null,
1295 | "metadata": {},
1296 | "outputs": [],
1297 | "source": [
1298 | "plt.plot(xr, np.log2(abs(ly - y).astype(float)))\n",
1299 | "plt.plot(xr, np.log2(abs(my - y).astype(float)))"
1300 | ]
1301 | },
1302 | {
1303 | "cell_type": "markdown",
1304 | "metadata": {},
1305 | "source": [
1306 | "### Exp(x)"
1307 | ]
1308 | },
1309 | {
1310 | "cell_type": "code",
1311 | "execution_count": null,
1312 | "metadata": {},
1313 | "outputs": [],
1314 | "source": [
1315 | "x = intrange(mp_to_fix(0.0), mp_to_fix(0.125), num = 10000)\n",
1316 | "xr = [fix_to_f(x) for x in x]"
1317 | ]
1318 | },
1319 | {
1320 | "cell_type": "code",
1321 | "execution_count": null,
1322 | "metadata": {},
1323 | "outputs": [],
1324 | "source": [
1325 | "y = np.array([mp_exp(x) for x in x])\n",
1326 | "yr = np.array([fix_to_f(y) for y in y])"
1327 | ]
1328 | },
1329 | {
1330 | "cell_type": "code",
1331 | "execution_count": null,
1332 | "metadata": {},
1333 | "outputs": [],
1334 | "source": [
1335 | "my = np.array([my_exp(x) for x in x])\n",
1336 | "myr = np.array([fix_to_f(y) for y in my])"
1337 | ]
1338 | },
1339 | {
1340 | "cell_type": "code",
1341 | "execution_count": null,
1342 | "metadata": {},
1343 | "outputs": [],
1344 | "source": [
1345 | "plt.plot(xr, yr)\n",
1346 | "plt.plot(xr, myr)"
1347 | ]
1348 | },
1349 | {
1350 | "cell_type": "code",
1351 | "execution_count": null,
1352 | "metadata": {},
1353 | "outputs": [],
1354 | "source": [
1355 | "plt.plot(xr, np.log2(abs(my - y).astype(float)))"
1356 | ]
1357 | },
1358 | {
1359 | "cell_type": "markdown",
1360 | "metadata": {},
1361 | "source": [
1362 | "### Ln(x)"
1363 | ]
1364 | },
1365 | {
1366 | "cell_type": "code",
1367 | "execution_count": null,
1368 | "metadata": {},
1369 | "outputs": [],
1370 | "source": [
1371 | "t = []"
1372 | ]
1373 | },
1374 | {
1375 | "cell_type": "code",
1376 | "execution_count": null,
1377 | "metadata": {},
1378 | "outputs": [],
1379 | "source": [
1380 | "x = intrange(LN_MIN_VAL, LN_MAX_VAL, num = 10000)\n",
1381 | "xr = [fix_to_f(x) for x in x]"
1382 | ]
1383 | },
1384 | {
1385 | "cell_type": "code",
1386 | "execution_count": null,
1387 | "metadata": {},
1388 | "outputs": [],
1389 | "source": [
1390 | "y = np.array([mp_ln(x) for x in x])\n",
1391 | "yr = np.array([fix_to_f(y) for y in y])"
1392 | ]
1393 | },
1394 | {
1395 | "cell_type": "code",
1396 | "execution_count": null,
1397 | "metadata": {},
1398 | "outputs": [],
1399 | "source": [
1400 | "ly = np.array([lib_ln(x) for x in x])\n",
1401 | "lyr = np.array([fix_to_f(y) for y in ly])"
1402 | ]
1403 | },
1404 | {
1405 | "cell_type": "code",
1406 | "execution_count": null,
1407 | "metadata": {},
1408 | "outputs": [],
1409 | "source": [
1410 | "lz = np.array([lib_ln(x, reductions='new', log='new') for x in x])\n",
1411 | "lzr = np.array([fix_to_f(z) for z in lz])"
1412 | ]
1413 | },
1414 | {
1415 | "cell_type": "code",
1416 | "execution_count": null,
1417 | "metadata": {},
1418 | "outputs": [],
1419 | "source": [
1420 | "plt.plot(xr, yr)\n",
1421 | "plt.plot(xr, lyr)\n",
1422 | "plt.plot(xr, lzr)"
1423 | ]
1424 | },
1425 | {
1426 | "cell_type": "code",
1427 | "execution_count": null,
1428 | "metadata": {},
1429 | "outputs": [],
1430 | "source": [
1431 | "plt.plot(xr, np.log2(abs(ly - y).astype(float)))\n",
1432 | "plt.plot(xr, np.log2(abs(lz - y).astype(float)))"
1433 | ]
1434 | },
1435 | {
1436 | "cell_type": "code",
1437 | "execution_count": null,
1438 | "metadata": {},
1439 | "outputs": [],
1440 | "source": [
1441 | "(fix_to_f(min(t)), fix_to_f(max(t)))"
1442 | ]
1443 | },
1444 | {
1445 | "cell_type": "code",
1446 | "execution_count": null,
1447 | "metadata": {},
1448 | "outputs": [],
1449 | "source": [
1450 | "plt.plot([fix_to_f(t) for t in t])"
1451 | ]
1452 | },
1453 | {
1454 | "cell_type": "code",
1455 | "execution_count": null,
1456 | "metadata": {},
1457 | "outputs": [],
1458 | "source": []
1459 | },
1460 | {
1461 | "cell_type": "code",
1462 | "execution_count": null,
1463 | "metadata": {},
1464 | "outputs": [],
1465 | "source": []
1466 | },
1467 | {
1468 | "cell_type": "code",
1469 | "execution_count": null,
1470 | "metadata": {},
1471 | "outputs": [],
1472 | "source": []
1473 | },
1474 | {
1475 | "cell_type": "code",
1476 | "execution_count": null,
1477 | "metadata": {},
1478 | "outputs": [],
1479 | "source": []
1480 | },
1481 | {
1482 | "cell_type": "code",
1483 | "execution_count": null,
1484 | "metadata": {},
1485 | "outputs": [],
1486 | "source": []
1487 | },
1488 | {
1489 | "cell_type": "code",
1490 | "execution_count": null,
1491 | "metadata": {},
1492 | "outputs": [],
1493 | "source": []
1494 | },
1495 | {
1496 | "cell_type": "code",
1497 | "execution_count": null,
1498 | "metadata": {},
1499 | "outputs": [],
1500 | "source": []
1501 | },
1502 | {
1503 | "cell_type": "code",
1504 | "execution_count": null,
1505 | "metadata": {},
1506 | "outputs": [],
1507 | "source": []
1508 | },
1509 | {
1510 | "cell_type": "code",
1511 | "execution_count": null,
1512 | "metadata": {},
1513 | "outputs": [],
1514 | "source": []
1515 | }
1516 | ],
1517 | "metadata": {
1518 | "kernelspec": {
1519 | "display_name": "Python 3 (ipykernel)",
1520 | "language": "python",
1521 | "name": "python3"
1522 | },
1523 | "language_info": {
1524 | "codemirror_mode": {
1525 | "name": "ipython",
1526 | "version": 3
1527 | },
1528 | "file_extension": ".py",
1529 | "mimetype": "text/x-python",
1530 | "name": "python",
1531 | "nbconvert_exporter": "python",
1532 | "pygments_lexer": "ipython3",
1533 | "version": "3.9.10"
1534 | }
1535 | },
1536 | "nbformat": 4,
1537 | "nbformat_minor": 4
1538 | }
1539 |
--------------------------------------------------------------------------------
/src/FixedPointMathLib.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: UNLICENSED
2 | pragma solidity ^0.8.10;
3 |
4 | import "./test/console.sol";
5 |
6 | library FixedPointMathLib {
7 |
8 | error Overflow();
9 | error LnNegativeUndefined();
10 |
11 | // Integer log2 (alternative implementation)
12 | // @returns floor(log2(x)) if x is nonzero, otherwise 0.
13 | // Consumes 317 gas. This could have been an 3 gas EVM opcode though.
14 | function ilog2_alt(uint256 x) internal returns (uint256 r) {
15 | unchecked {
16 | // Repeat first zero all the way to the right
17 | x |= x >> 1;
18 | x |= x >> 2;
19 | x |= x >> 4;
20 | x |= x >> 8;
21 | x |= x >> 16;
22 | x |= x >> 32;
23 | x |= x >> 64;
24 | x |= x >> 128;
25 |
26 | // Count 32 bit chunks
27 | r = x & 0x100000001000000010000000100000001000000010000000100000001;
28 | r *= 0x20000000200000002000000020000000200000002000000020;
29 | r >>= 224;
30 |
31 | // Extract highest bit
32 | x ^= x >> 1;
33 |
34 | // Copy to lowest 32 bit chunk
35 | x |= x >> 32;
36 | x |= x >> 64;
37 | x |= x >> 128;
38 | // No need to clear the other chunks
39 |
40 | // Map to 0-31 using the B(2, 5) de Bruijn sequence 0x077CB531.
41 | // See
42 | x = ((x * 0x077CB531) >> 27) & 0x1f;
43 |
44 | // Use a bytes32 32 entry lookup table
45 | assembly {
46 | // Need assembly here because solidity introduces an uncessary bounds
47 | // check.
48 | r := add(r, byte(x, 0x11c021d0e18031e16140f191104081f1b0d17151310071a0c12060b050a09))
49 | }
50 | }
51 | }
52 |
53 | // Integer log2
54 | // @returns floor(log2(x)) if x is nonzero, otherwise 0. This is the same
55 | // as the location of the highest set bit.
56 | // Consumes 232 gas. This could have been an 3 gas EVM opcode though.
57 | function ilog2(uint256 x) internal returns (uint256 r) {
58 | assembly {
59 | r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
60 | r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
61 | r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
62 | r := or(r, shl(4, lt(0xffff, shr(r, x))))
63 | r := or(r, shl(3, lt(0xff, shr(r, x))))
64 | r := or(r, shl(2, lt(0xf, shr(r, x))))
65 | r := or(r, shl(1, lt(0x3, shr(r, x))))
66 | r := or(r, lt(0x1, shr(r, x)))
67 | }
68 | }
69 |
70 | function ln_pub(int256 x) public returns (int256 r) {
71 | return ln(x);
72 | }
73 |
74 | // Computes ln(x) in 1e18 fixed point.
75 | // Reverts if x is negative or zero.
76 | // Consumes 670 gas.
77 | function ln(int256 x) internal returns (int256 r) { unchecked {
78 | if (x < 1) {
79 | if (x < 0) revert LnNegativeUndefined();
80 | revert Overflow();
81 | }
82 |
83 | // We want to convert x from 10**18 fixed point to 2**96 fixed point.
84 | // We do this by multiplying by 2**96 / 10**18.
85 | // But since ln(x * C) = ln(x) + ln(C), we can simply do nothing here
86 | // and add ln(2**96 / 10**18) at the end.
87 |
88 | // Reduce range of x to (1, 2) * 2**96
89 | // ln(2^k * x) = k * ln(2) + ln(x)
90 | // Note: inlining ilog2 saves 8 gas.
91 | int256 k = int256(ilog2(uint256(x))) - 96;
92 | x <<= uint256(159 - k);
93 | x = int256(uint256(x) >> 159);
94 |
95 | // Evaluate using a (8, 8)-term rational approximation
96 | // p is made monic, we will multiply by a scale factor later
97 | int256 p = x + 3273285459638523848632254066296;
98 | p = (p * x >> 96) + 24828157081833163892658089445524;
99 | p = (p * x >> 96) + 43456485725739037958740375743393;
100 | p = (p * x >> 96) - 11111509109440967052023855526967;
101 | p = (p * x >> 96) - 45023709667254063763336534515857;
102 | p = (p * x >> 96) - 14706773417378608786704636184526;
103 | p = p * x - (795164235651350426258249787498 << 96);
104 | //emit log_named_int("p", p);
105 | // We leave p in 2**192 basis so we don't need to scale it back up for the division.
106 | // q is monic by convention
107 | int256 q = x + 5573035233440673466300451813936;
108 | q = (q * x >> 96) + 71694874799317883764090561454958;
109 | q = (q * x >> 96) + 283447036172924575727196451306956;
110 | q = (q * x >> 96) + 401686690394027663651624208769553;
111 | q = (q * x >> 96) + 204048457590392012362485061816622;
112 | q = (q * x >> 96) + 31853899698501571402653359427138;
113 | q = (q * x >> 96) + 909429971244387300277376558375;
114 | assembly {
115 | // Div in assembly because solidity adds a zero check despite the `unchecked`.
116 | // The q polynomial is known not to have zeros in the domain. (All roots are complex)
117 | // No scaling required because p is already 2**96 too large.
118 | r := sdiv(p, q)
119 | }
120 | // r is in the range (0, 0.125) * 2**96
121 |
122 | // Finalization, we need to
123 | // * multiply by the scale factor s = 5.549…
124 | // * add ln(2**96 / 10**18)
125 | // * add k * ln(2)
126 | // * multiply by 10**18 / 2**96 = 5**18 >> 78
127 | // mul s * 5e18 * 2**96, base is now 5**18 * 2**192
128 | r *= 1677202110996718588342820967067443963516166;
129 | // add ln(2) * k * 5e18 * 2**192
130 | r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;
131 | // add ln(2**96 / 10**18) * 5e18 * 2**192
132 | r += 600920179829731861736702779321621459595472258049074101567377883020018308;
133 | // base conversion: mul 2**18 / 2**192
134 | r >>= 174;
135 | }}
136 |
137 | // Computes e^x in 1e18 fixed point.
138 | function exp(int256 x) internal pure returns (int256 r) { unchecked {
139 | // Input x is in fixed point format, with scale factor 1/1e18.
140 |
141 | // When the result is < 0.5 we return zero. This happens when
142 | // x <= floor(log(0.5e18) * 1e18) ~ -42e18
143 | if (x <= -42139678854452767551) {
144 | return 0;
145 | }
146 |
147 | // When the result is > (2**255 - 1) / 1e18 we can not represent it
148 | // as an int256. This happens when x >= floor(log((2**255 -1) / 1e18) * 1e18) ~ 135.
149 | if (x >= 135305999368893231589) revert Overflow();
150 |
151 | // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96
152 | // for more intermediate precision and a binary basis. This base conversion
153 | // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.
154 | x = (x << 78) / 5**18;
155 |
156 | // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers of two
157 | // such that exp(x) = exp(x') * 2**k, where k is an integer.
158 | // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).
159 | int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;
160 | x = x - k * 54916777467707473351141471128;
161 | // k is in the range [-61, 195].
162 |
163 | // Evaluate using a (6, 7)-term rational approximation
164 | // p is made monic, we will multiply by a scale factor later
165 | int256 p = x + 2772001395605857295435445496992;
166 | p = (p * x >> 96) + 44335888930127919016834873520032;
167 | p = (p * x >> 96) + 398888492587501845352592340339721;
168 | p = (p * x >> 96) + 1993839819670624470859228494792842;
169 | p = p * x + (4385272521454847904632057985693276 << 96);
170 | // We leave p in 2**192 basis so we don't need to scale it back up for the division.
171 | // Evaluate using using Knuth's scheme from p. 491.
172 | int256 z = x + 750530180792738023273180420736;
173 | z = (z * x >> 96) + 32788456221302202726307501949080;
174 | int256 w = x - 2218138959503481824038194425854;
175 | w = (w * z >> 96) + 892943633302991980437332862907700;
176 | int256 q = z + w - 78174809823045304726920794422040;
177 | q = (q * w >> 96) + 4203224763890128580604056984195872;
178 | assembly {
179 | // Div in assembly because solidity adds a zero check despite the `unchecked`.
180 | // The q polynomial is known not to have zeros in the domain. (All roots are complex)
181 | // No scaling required because p is already 2**96 too large.
182 | r := sdiv(p, q)
183 | }
184 | // r should be in the range (0.09, 0.25) * 2**96.
185 |
186 | // We now need to multiply r by
187 | // * the scale factor s = ~6.031367120...,
188 | // * the 2**k factor from the range reduction, and
189 | // * the 1e18 / 2**96 factor for base converison.
190 | // We do all of this at once, with an intermediate result in 2**213 basis
191 | // so the final right shift is always by a positive amount.
192 | r = int((uint(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));
193 | }}
194 | }
195 |
--------------------------------------------------------------------------------
/src/test/FixedPointMathLib.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: UNLICENSED
2 | pragma solidity 0.8.10;
3 |
4 | import "ds-test/test.sol";
5 | import "../FixedPointMathLib.sol";
6 | import "./console.sol";
7 |
8 | contract FixedPointMathLibTest is DSTest {
9 | function setUp() public {}
10 |
11 | function testIlog1() public {
12 | FixedPointMathLib.ilog2(2 ** 196 - 1);
13 | }
14 |
15 | function testIlog2() public {
16 | FixedPointMathLib.ilog2(1e18);
17 | FixedPointMathLib.ilog2(1e20);
18 | }
19 |
20 | function testIlog() public {
21 | assertEq(FixedPointMathLib.ilog2(0), 0);
22 | for(uint256 i = 1; i < 255; i++) {
23 | assertEq(FixedPointMathLib.ilog2((1 << i) - 1), i - 1);
24 | assertEq(FixedPointMathLib.ilog2((1 << i)), i);
25 | assertEq(FixedPointMathLib.ilog2((1 << i) + 1), i);
26 | }
27 | }
28 |
29 | function testIlogGas() public {
30 | uint256 count = 0;
31 | uint256 sum = 0;
32 | uint256 sum_sq = 0;
33 | for(uint256 i = 1; i < 255; i++) {
34 | uint256 k = (1 << i) - 1;
35 | uint g0 = gasleft();
36 | FixedPointMathLib.ilog2(k);
37 | uint g1 = gasleft();
38 | sum += g0 - g1;
39 | sum_sq += (g0 - g1) * (g0 - g1);
40 | ++count;
41 | ++k;
42 | g0 = gasleft();
43 | FixedPointMathLib.ilog2(k);
44 | g1 = gasleft();
45 | sum += g0 - g1;
46 | sum_sq += (g0 - g1) * (g0 - g1);
47 | ++count;
48 | ++k;
49 | g0 = gasleft();
50 | FixedPointMathLib.ilog2(k);
51 | g1 = gasleft();
52 | sum += g0 - g1;
53 | sum_sq += (g0 - g1) * (g0 - g1);
54 | ++count;
55 | }
56 | console.Log("gas", sum / count);
57 | console.Log("gas_var", (sum_sq - sum * sum / count)/ (count - 1));
58 | }
59 |
60 | function testLn1() public {
61 | assertEq(FixedPointMathLib.ln(1e18), 0);
62 | }
63 |
64 | function testLn() public {
65 | assertEq(FixedPointMathLib.ln(1e18), 0);
66 |
67 | // Actual: 999999999999999999.8674576…
68 | assertEq(FixedPointMathLib.ln(2718281828459045235), 999999999999999999);
69 |
70 | // Actual: 2461607324344817917.963296…
71 | assertEq(FixedPointMathLib.ln(11723640096265400935), 2461607324344817918);
72 | }
73 |
74 | function testLnSmall() public {
75 | // Actual: -41446531673892822312.3238461…
76 | assertEq(FixedPointMathLib.ln(1), -41446531673892822313);
77 |
78 | // Actual: -37708862055609454006.40601608…
79 | assertEq(FixedPointMathLib.ln(42), -37708862055609454007);
80 |
81 | // Actual: -32236191301916639576.251880365581…
82 | assertEq(FixedPointMathLib.ln(1e4), -32236191301916639577);
83 |
84 | // Actual: -20723265836946411156.161923092…
85 | assertEq(FixedPointMathLib.ln(1e9), -20723265836946411157);
86 | }
87 |
88 | function testLnBig() public {
89 | // Actual: 135305999368893231589.070344787…
90 | assertEq(FixedPointMathLib.ln(2**255 - 1), 135305999368893231589);
91 |
92 | // Actual: 76388489021297880288.605614463571…
93 | assertEq(FixedPointMathLib.ln(2**170), 76388489021297880288);
94 |
95 | // Actual: 47276307437780177293.081865…
96 | assertEq(FixedPointMathLib.ln(2**128), 47276307437780177293);
97 | }
98 |
99 | function testLnGas() public {
100 | uint256 count = 0;
101 | uint256 sum = 0;
102 | uint256 sum_sq = 0;
103 | for(uint256 i = 1; i < 255; i++) {
104 | int256 k = int256(1 << i) - 1;
105 | uint g0 = gasleft();
106 | FixedPointMathLib.ln(k);
107 | uint g1 = gasleft();
108 | sum += g0 - g1;
109 | sum_sq += (g0 - g1) * (g0 - g1);
110 | ++count;
111 | ++k;
112 | g0 = gasleft();
113 | FixedPointMathLib.ln(k);
114 | g1 = gasleft();
115 | sum += g0 - g1;
116 | sum_sq += (g0 - g1) * (g0 - g1);
117 | ++count;
118 | ++k;
119 | g0 = gasleft();
120 | FixedPointMathLib.ln(k);
121 | g1 = gasleft();
122 | sum += g0 - g1;
123 | sum_sq += (g0 - g1) * (g0 - g1);
124 | ++count;
125 | }
126 | console.Log("gas", sum / count);
127 | console.Log("gas_var", (sum_sq - sum * sum / count)/ (count - 1));
128 | }
129 |
130 | function testExp1() public {
131 | assertEq(FixedPointMathLib.exp(-1e18), 367879441171442321);
132 | }
133 |
134 | function testSmallest() public {
135 | FixedPointMathLib.exp(-42139678854452767550);
136 | }
137 |
138 | function testLargest() public {
139 | FixedPointMathLib.exp(135305999368893231588);
140 | }
141 |
142 | function testSome() public {
143 | console.logInt(FixedPointMathLib.exp(5e18));
144 | }
145 |
146 | function testExpGas() public {
147 | uint g0 = gasleft();
148 | FixedPointMathLib.exp(133e18);
149 | uint g1 = gasleft();
150 | FixedPointMathLib.exp(-23e18);
151 | uint g2 = gasleft();
152 | FixedPointMathLib.exp(5e18);
153 | uint g3 = gasleft();
154 | console.logUint(g0 - g1);
155 | console.logUint(g1 - g2);
156 | console.logUint(g2 - g3);
157 | }
158 |
159 | function testExp3() public {
160 | FixedPointMathLib.exp(133e18);
161 | FixedPointMathLib.exp(10e18);
162 | FixedPointMathLib.exp(-23e18);
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/test/console.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.22 <0.9.0;
3 |
4 | library console {
5 | address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);
6 |
7 | // Copied from https://github.com/dapphub/ds-test/blob/master/src/test.sol
8 | event log_named_int (string key, int val);
9 | event log_named_uint (string key, uint val);
10 |
11 |
12 | function Log(string memory name, int p0) internal {
13 | emit log_named_int(name, p0);
14 | }
15 |
16 | function Log(string memory name, uint p0) internal {
17 | emit log_named_uint(name, p0);
18 | }
19 |
20 | function _sendLogPayload(bytes memory payload) private view {
21 | uint256 payloadLength = payload.length;
22 | address consoleAddress = CONSOLE_ADDRESS;
23 | assembly {
24 | let payloadStart := add(payload, 32)
25 | let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
26 | }
27 | }
28 |
29 | function log() internal view {
30 | _sendLogPayload(abi.encodeWithSignature("log()"));
31 | }
32 |
33 | function logInt(int p0) internal view {
34 | _sendLogPayload(abi.encodeWithSignature("log(int)", p0));
35 | }
36 |
37 | function logUint(uint p0) internal view {
38 | _sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
39 | }
40 |
41 | function logString(string memory p0) internal view {
42 | _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
43 | }
44 |
45 | function logBool(bool p0) internal view {
46 | _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
47 | }
48 |
49 | function logAddress(address p0) internal view {
50 | _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
51 | }
52 |
53 | function logBytes(bytes memory p0) internal view {
54 | _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
55 | }
56 |
57 | function logBytes1(bytes1 p0) internal view {
58 | _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
59 | }
60 |
61 | function logBytes2(bytes2 p0) internal view {
62 | _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
63 | }
64 |
65 | function logBytes3(bytes3 p0) internal view {
66 | _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
67 | }
68 |
69 | function logBytes4(bytes4 p0) internal view {
70 | _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
71 | }
72 |
73 | function logBytes5(bytes5 p0) internal view {
74 | _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
75 | }
76 |
77 | function logBytes6(bytes6 p0) internal view {
78 | _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
79 | }
80 |
81 | function logBytes7(bytes7 p0) internal view {
82 | _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
83 | }
84 |
85 | function logBytes8(bytes8 p0) internal view {
86 | _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
87 | }
88 |
89 | function logBytes9(bytes9 p0) internal view {
90 | _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
91 | }
92 |
93 | function logBytes10(bytes10 p0) internal view {
94 | _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
95 | }
96 |
97 | function logBytes11(bytes11 p0) internal view {
98 | _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
99 | }
100 |
101 | function logBytes12(bytes12 p0) internal view {
102 | _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
103 | }
104 |
105 | function logBytes13(bytes13 p0) internal view {
106 | _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
107 | }
108 |
109 | function logBytes14(bytes14 p0) internal view {
110 | _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
111 | }
112 |
113 | function logBytes15(bytes15 p0) internal view {
114 | _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
115 | }
116 |
117 | function logBytes16(bytes16 p0) internal view {
118 | _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
119 | }
120 |
121 | function logBytes17(bytes17 p0) internal view {
122 | _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
123 | }
124 |
125 | function logBytes18(bytes18 p0) internal view {
126 | _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
127 | }
128 |
129 | function logBytes19(bytes19 p0) internal view {
130 | _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
131 | }
132 |
133 | function logBytes20(bytes20 p0) internal view {
134 | _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
135 | }
136 |
137 | function logBytes21(bytes21 p0) internal view {
138 | _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
139 | }
140 |
141 | function logBytes22(bytes22 p0) internal view {
142 | _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
143 | }
144 |
145 | function logBytes23(bytes23 p0) internal view {
146 | _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
147 | }
148 |
149 | function logBytes24(bytes24 p0) internal view {
150 | _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
151 | }
152 |
153 | function logBytes25(bytes25 p0) internal view {
154 | _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
155 | }
156 |
157 | function logBytes26(bytes26 p0) internal view {
158 | _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
159 | }
160 |
161 | function logBytes27(bytes27 p0) internal view {
162 | _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
163 | }
164 |
165 | function logBytes28(bytes28 p0) internal view {
166 | _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
167 | }
168 |
169 | function logBytes29(bytes29 p0) internal view {
170 | _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
171 | }
172 |
173 | function logBytes30(bytes30 p0) internal view {
174 | _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
175 | }
176 |
177 | function logBytes31(bytes31 p0) internal view {
178 | _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
179 | }
180 |
181 | function logBytes32(bytes32 p0) internal view {
182 | _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
183 | }
184 |
185 | function log(uint p0) internal view {
186 | _sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
187 | }
188 |
189 | function log(string memory p0) internal view {
190 | _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
191 | }
192 |
193 | function log(bool p0) internal view {
194 | _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
195 | }
196 |
197 | function log(address p0) internal view {
198 | _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
199 | }
200 |
201 | function log(uint p0, uint p1) internal view {
202 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1));
203 | }
204 |
205 | function log(uint p0, string memory p1) internal view {
206 | _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1));
207 | }
208 |
209 | function log(uint p0, bool p1) internal view {
210 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1));
211 | }
212 |
213 | function log(uint p0, address p1) internal view {
214 | _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1));
215 | }
216 |
217 | function log(string memory p0, uint p1) internal view {
218 | _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1));
219 | }
220 |
221 | function log(string memory p0, string memory p1) internal view {
222 | _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
223 | }
224 |
225 | function log(string memory p0, bool p1) internal view {
226 | _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
227 | }
228 |
229 | function log(string memory p0, address p1) internal view {
230 | _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
231 | }
232 |
233 | function log(bool p0, uint p1) internal view {
234 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1));
235 | }
236 |
237 | function log(bool p0, string memory p1) internal view {
238 | _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
239 | }
240 |
241 | function log(bool p0, bool p1) internal view {
242 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
243 | }
244 |
245 | function log(bool p0, address p1) internal view {
246 | _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
247 | }
248 |
249 | function log(address p0, uint p1) internal view {
250 | _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1));
251 | }
252 |
253 | function log(address p0, string memory p1) internal view {
254 | _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
255 | }
256 |
257 | function log(address p0, bool p1) internal view {
258 | _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
259 | }
260 |
261 | function log(address p0, address p1) internal view {
262 | _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
263 | }
264 |
265 | function log(uint p0, uint p1, uint p2) internal view {
266 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2));
267 | }
268 |
269 | function log(uint p0, uint p1, string memory p2) internal view {
270 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2));
271 | }
272 |
273 | function log(uint p0, uint p1, bool p2) internal view {
274 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2));
275 | }
276 |
277 | function log(uint p0, uint p1, address p2) internal view {
278 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2));
279 | }
280 |
281 | function log(uint p0, string memory p1, uint p2) internal view {
282 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2));
283 | }
284 |
285 | function log(uint p0, string memory p1, string memory p2) internal view {
286 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2));
287 | }
288 |
289 | function log(uint p0, string memory p1, bool p2) internal view {
290 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2));
291 | }
292 |
293 | function log(uint p0, string memory p1, address p2) internal view {
294 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2));
295 | }
296 |
297 | function log(uint p0, bool p1, uint p2) internal view {
298 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2));
299 | }
300 |
301 | function log(uint p0, bool p1, string memory p2) internal view {
302 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2));
303 | }
304 |
305 | function log(uint p0, bool p1, bool p2) internal view {
306 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2));
307 | }
308 |
309 | function log(uint p0, bool p1, address p2) internal view {
310 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2));
311 | }
312 |
313 | function log(uint p0, address p1, uint p2) internal view {
314 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2));
315 | }
316 |
317 | function log(uint p0, address p1, string memory p2) internal view {
318 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2));
319 | }
320 |
321 | function log(uint p0, address p1, bool p2) internal view {
322 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2));
323 | }
324 |
325 | function log(uint p0, address p1, address p2) internal view {
326 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2));
327 | }
328 |
329 | function log(string memory p0, uint p1, uint p2) internal view {
330 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2));
331 | }
332 |
333 | function log(string memory p0, uint p1, string memory p2) internal view {
334 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2));
335 | }
336 |
337 | function log(string memory p0, uint p1, bool p2) internal view {
338 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2));
339 | }
340 |
341 | function log(string memory p0, uint p1, address p2) internal view {
342 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2));
343 | }
344 |
345 | function log(string memory p0, string memory p1, uint p2) internal view {
346 | _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2));
347 | }
348 |
349 | function log(string memory p0, string memory p1, string memory p2) internal view {
350 | _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
351 | }
352 |
353 | function log(string memory p0, string memory p1, bool p2) internal view {
354 | _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
355 | }
356 |
357 | function log(string memory p0, string memory p1, address p2) internal view {
358 | _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
359 | }
360 |
361 | function log(string memory p0, bool p1, uint p2) internal view {
362 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2));
363 | }
364 |
365 | function log(string memory p0, bool p1, string memory p2) internal view {
366 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
367 | }
368 |
369 | function log(string memory p0, bool p1, bool p2) internal view {
370 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
371 | }
372 |
373 | function log(string memory p0, bool p1, address p2) internal view {
374 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
375 | }
376 |
377 | function log(string memory p0, address p1, uint p2) internal view {
378 | _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2));
379 | }
380 |
381 | function log(string memory p0, address p1, string memory p2) internal view {
382 | _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
383 | }
384 |
385 | function log(string memory p0, address p1, bool p2) internal view {
386 | _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
387 | }
388 |
389 | function log(string memory p0, address p1, address p2) internal view {
390 | _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
391 | }
392 |
393 | function log(bool p0, uint p1, uint p2) internal view {
394 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2));
395 | }
396 |
397 | function log(bool p0, uint p1, string memory p2) internal view {
398 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2));
399 | }
400 |
401 | function log(bool p0, uint p1, bool p2) internal view {
402 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2));
403 | }
404 |
405 | function log(bool p0, uint p1, address p2) internal view {
406 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2));
407 | }
408 |
409 | function log(bool p0, string memory p1, uint p2) internal view {
410 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2));
411 | }
412 |
413 | function log(bool p0, string memory p1, string memory p2) internal view {
414 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
415 | }
416 |
417 | function log(bool p0, string memory p1, bool p2) internal view {
418 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
419 | }
420 |
421 | function log(bool p0, string memory p1, address p2) internal view {
422 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
423 | }
424 |
425 | function log(bool p0, bool p1, uint p2) internal view {
426 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2));
427 | }
428 |
429 | function log(bool p0, bool p1, string memory p2) internal view {
430 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
431 | }
432 |
433 | function log(bool p0, bool p1, bool p2) internal view {
434 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
435 | }
436 |
437 | function log(bool p0, bool p1, address p2) internal view {
438 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
439 | }
440 |
441 | function log(bool p0, address p1, uint p2) internal view {
442 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2));
443 | }
444 |
445 | function log(bool p0, address p1, string memory p2) internal view {
446 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
447 | }
448 |
449 | function log(bool p0, address p1, bool p2) internal view {
450 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
451 | }
452 |
453 | function log(bool p0, address p1, address p2) internal view {
454 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
455 | }
456 |
457 | function log(address p0, uint p1, uint p2) internal view {
458 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2));
459 | }
460 |
461 | function log(address p0, uint p1, string memory p2) internal view {
462 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2));
463 | }
464 |
465 | function log(address p0, uint p1, bool p2) internal view {
466 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2));
467 | }
468 |
469 | function log(address p0, uint p1, address p2) internal view {
470 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2));
471 | }
472 |
473 | function log(address p0, string memory p1, uint p2) internal view {
474 | _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2));
475 | }
476 |
477 | function log(address p0, string memory p1, string memory p2) internal view {
478 | _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
479 | }
480 |
481 | function log(address p0, string memory p1, bool p2) internal view {
482 | _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
483 | }
484 |
485 | function log(address p0, string memory p1, address p2) internal view {
486 | _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
487 | }
488 |
489 | function log(address p0, bool p1, uint p2) internal view {
490 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2));
491 | }
492 |
493 | function log(address p0, bool p1, string memory p2) internal view {
494 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
495 | }
496 |
497 | function log(address p0, bool p1, bool p2) internal view {
498 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
499 | }
500 |
501 | function log(address p0, bool p1, address p2) internal view {
502 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
503 | }
504 |
505 | function log(address p0, address p1, uint p2) internal view {
506 | _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2));
507 | }
508 |
509 | function log(address p0, address p1, string memory p2) internal view {
510 | _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
511 | }
512 |
513 | function log(address p0, address p1, bool p2) internal view {
514 | _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
515 | }
516 |
517 | function log(address p0, address p1, address p2) internal view {
518 | _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
519 | }
520 |
521 | function log(uint p0, uint p1, uint p2, uint p3) internal view {
522 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3));
523 | }
524 |
525 | function log(uint p0, uint p1, uint p2, string memory p3) internal view {
526 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3));
527 | }
528 |
529 | function log(uint p0, uint p1, uint p2, bool p3) internal view {
530 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3));
531 | }
532 |
533 | function log(uint p0, uint p1, uint p2, address p3) internal view {
534 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3));
535 | }
536 |
537 | function log(uint p0, uint p1, string memory p2, uint p3) internal view {
538 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3));
539 | }
540 |
541 | function log(uint p0, uint p1, string memory p2, string memory p3) internal view {
542 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3));
543 | }
544 |
545 | function log(uint p0, uint p1, string memory p2, bool p3) internal view {
546 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3));
547 | }
548 |
549 | function log(uint p0, uint p1, string memory p2, address p3) internal view {
550 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3));
551 | }
552 |
553 | function log(uint p0, uint p1, bool p2, uint p3) internal view {
554 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3));
555 | }
556 |
557 | function log(uint p0, uint p1, bool p2, string memory p3) internal view {
558 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3));
559 | }
560 |
561 | function log(uint p0, uint p1, bool p2, bool p3) internal view {
562 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3));
563 | }
564 |
565 | function log(uint p0, uint p1, bool p2, address p3) internal view {
566 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3));
567 | }
568 |
569 | function log(uint p0, uint p1, address p2, uint p3) internal view {
570 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3));
571 | }
572 |
573 | function log(uint p0, uint p1, address p2, string memory p3) internal view {
574 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3));
575 | }
576 |
577 | function log(uint p0, uint p1, address p2, bool p3) internal view {
578 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3));
579 | }
580 |
581 | function log(uint p0, uint p1, address p2, address p3) internal view {
582 | _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3));
583 | }
584 |
585 | function log(uint p0, string memory p1, uint p2, uint p3) internal view {
586 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3));
587 | }
588 |
589 | function log(uint p0, string memory p1, uint p2, string memory p3) internal view {
590 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3));
591 | }
592 |
593 | function log(uint p0, string memory p1, uint p2, bool p3) internal view {
594 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3));
595 | }
596 |
597 | function log(uint p0, string memory p1, uint p2, address p3) internal view {
598 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3));
599 | }
600 |
601 | function log(uint p0, string memory p1, string memory p2, uint p3) internal view {
602 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3));
603 | }
604 |
605 | function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {
606 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3));
607 | }
608 |
609 | function log(uint p0, string memory p1, string memory p2, bool p3) internal view {
610 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3));
611 | }
612 |
613 | function log(uint p0, string memory p1, string memory p2, address p3) internal view {
614 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3));
615 | }
616 |
617 | function log(uint p0, string memory p1, bool p2, uint p3) internal view {
618 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3));
619 | }
620 |
621 | function log(uint p0, string memory p1, bool p2, string memory p3) internal view {
622 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3));
623 | }
624 |
625 | function log(uint p0, string memory p1, bool p2, bool p3) internal view {
626 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3));
627 | }
628 |
629 | function log(uint p0, string memory p1, bool p2, address p3) internal view {
630 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3));
631 | }
632 |
633 | function log(uint p0, string memory p1, address p2, uint p3) internal view {
634 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3));
635 | }
636 |
637 | function log(uint p0, string memory p1, address p2, string memory p3) internal view {
638 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3));
639 | }
640 |
641 | function log(uint p0, string memory p1, address p2, bool p3) internal view {
642 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3));
643 | }
644 |
645 | function log(uint p0, string memory p1, address p2, address p3) internal view {
646 | _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3));
647 | }
648 |
649 | function log(uint p0, bool p1, uint p2, uint p3) internal view {
650 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3));
651 | }
652 |
653 | function log(uint p0, bool p1, uint p2, string memory p3) internal view {
654 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3));
655 | }
656 |
657 | function log(uint p0, bool p1, uint p2, bool p3) internal view {
658 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3));
659 | }
660 |
661 | function log(uint p0, bool p1, uint p2, address p3) internal view {
662 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3));
663 | }
664 |
665 | function log(uint p0, bool p1, string memory p2, uint p3) internal view {
666 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3));
667 | }
668 |
669 | function log(uint p0, bool p1, string memory p2, string memory p3) internal view {
670 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3));
671 | }
672 |
673 | function log(uint p0, bool p1, string memory p2, bool p3) internal view {
674 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3));
675 | }
676 |
677 | function log(uint p0, bool p1, string memory p2, address p3) internal view {
678 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3));
679 | }
680 |
681 | function log(uint p0, bool p1, bool p2, uint p3) internal view {
682 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3));
683 | }
684 |
685 | function log(uint p0, bool p1, bool p2, string memory p3) internal view {
686 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3));
687 | }
688 |
689 | function log(uint p0, bool p1, bool p2, bool p3) internal view {
690 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3));
691 | }
692 |
693 | function log(uint p0, bool p1, bool p2, address p3) internal view {
694 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3));
695 | }
696 |
697 | function log(uint p0, bool p1, address p2, uint p3) internal view {
698 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3));
699 | }
700 |
701 | function log(uint p0, bool p1, address p2, string memory p3) internal view {
702 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3));
703 | }
704 |
705 | function log(uint p0, bool p1, address p2, bool p3) internal view {
706 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3));
707 | }
708 |
709 | function log(uint p0, bool p1, address p2, address p3) internal view {
710 | _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3));
711 | }
712 |
713 | function log(uint p0, address p1, uint p2, uint p3) internal view {
714 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3));
715 | }
716 |
717 | function log(uint p0, address p1, uint p2, string memory p3) internal view {
718 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3));
719 | }
720 |
721 | function log(uint p0, address p1, uint p2, bool p3) internal view {
722 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3));
723 | }
724 |
725 | function log(uint p0, address p1, uint p2, address p3) internal view {
726 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3));
727 | }
728 |
729 | function log(uint p0, address p1, string memory p2, uint p3) internal view {
730 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3));
731 | }
732 |
733 | function log(uint p0, address p1, string memory p2, string memory p3) internal view {
734 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3));
735 | }
736 |
737 | function log(uint p0, address p1, string memory p2, bool p3) internal view {
738 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3));
739 | }
740 |
741 | function log(uint p0, address p1, string memory p2, address p3) internal view {
742 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3));
743 | }
744 |
745 | function log(uint p0, address p1, bool p2, uint p3) internal view {
746 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3));
747 | }
748 |
749 | function log(uint p0, address p1, bool p2, string memory p3) internal view {
750 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3));
751 | }
752 |
753 | function log(uint p0, address p1, bool p2, bool p3) internal view {
754 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3));
755 | }
756 |
757 | function log(uint p0, address p1, bool p2, address p3) internal view {
758 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3));
759 | }
760 |
761 | function log(uint p0, address p1, address p2, uint p3) internal view {
762 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3));
763 | }
764 |
765 | function log(uint p0, address p1, address p2, string memory p3) internal view {
766 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3));
767 | }
768 |
769 | function log(uint p0, address p1, address p2, bool p3) internal view {
770 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3));
771 | }
772 |
773 | function log(uint p0, address p1, address p2, address p3) internal view {
774 | _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3));
775 | }
776 |
777 | function log(string memory p0, uint p1, uint p2, uint p3) internal view {
778 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3));
779 | }
780 |
781 | function log(string memory p0, uint p1, uint p2, string memory p3) internal view {
782 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3));
783 | }
784 |
785 | function log(string memory p0, uint p1, uint p2, bool p3) internal view {
786 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3));
787 | }
788 |
789 | function log(string memory p0, uint p1, uint p2, address p3) internal view {
790 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3));
791 | }
792 |
793 | function log(string memory p0, uint p1, string memory p2, uint p3) internal view {
794 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3));
795 | }
796 |
797 | function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {
798 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3));
799 | }
800 |
801 | function log(string memory p0, uint p1, string memory p2, bool p3) internal view {
802 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3));
803 | }
804 |
805 | function log(string memory p0, uint p1, string memory p2, address p3) internal view {
806 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3));
807 | }
808 |
809 | function log(string memory p0, uint p1, bool p2, uint p3) internal view {
810 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3));
811 | }
812 |
813 | function log(string memory p0, uint p1, bool p2, string memory p3) internal view {
814 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3));
815 | }
816 |
817 | function log(string memory p0, uint p1, bool p2, bool p3) internal view {
818 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3));
819 | }
820 |
821 | function log(string memory p0, uint p1, bool p2, address p3) internal view {
822 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3));
823 | }
824 |
825 | function log(string memory p0, uint p1, address p2, uint p3) internal view {
826 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3));
827 | }
828 |
829 | function log(string memory p0, uint p1, address p2, string memory p3) internal view {
830 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3));
831 | }
832 |
833 | function log(string memory p0, uint p1, address p2, bool p3) internal view {
834 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3));
835 | }
836 |
837 | function log(string memory p0, uint p1, address p2, address p3) internal view {
838 | _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3));
839 | }
840 |
841 | function log(string memory p0, string memory p1, uint p2, uint p3) internal view {
842 | _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3));
843 | }
844 |
845 | function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {
846 | _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3));
847 | }
848 |
849 | function log(string memory p0, string memory p1, uint p2, bool p3) internal view {
850 | _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3));
851 | }
852 |
853 | function log(string memory p0, string memory p1, uint p2, address p3) internal view {
854 | _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3));
855 | }
856 |
857 | function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {
858 | _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3));
859 | }
860 |
861 | function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
862 | _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
863 | }
864 |
865 | function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {
866 | _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
867 | }
868 |
869 | function log(string memory p0, string memory p1, string memory p2, address p3) internal view {
870 | _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
871 | }
872 |
873 | function log(string memory p0, string memory p1, bool p2, uint p3) internal view {
874 | _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3));
875 | }
876 |
877 | function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
878 | _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
879 | }
880 |
881 | function log(string memory p0, string memory p1, bool p2, bool p3) internal view {
882 | _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
883 | }
884 |
885 | function log(string memory p0, string memory p1, bool p2, address p3) internal view {
886 | _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
887 | }
888 |
889 | function log(string memory p0, string memory p1, address p2, uint p3) internal view {
890 | _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3));
891 | }
892 |
893 | function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
894 | _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
895 | }
896 |
897 | function log(string memory p0, string memory p1, address p2, bool p3) internal view {
898 | _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
899 | }
900 |
901 | function log(string memory p0, string memory p1, address p2, address p3) internal view {
902 | _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
903 | }
904 |
905 | function log(string memory p0, bool p1, uint p2, uint p3) internal view {
906 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3));
907 | }
908 |
909 | function log(string memory p0, bool p1, uint p2, string memory p3) internal view {
910 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3));
911 | }
912 |
913 | function log(string memory p0, bool p1, uint p2, bool p3) internal view {
914 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3));
915 | }
916 |
917 | function log(string memory p0, bool p1, uint p2, address p3) internal view {
918 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3));
919 | }
920 |
921 | function log(string memory p0, bool p1, string memory p2, uint p3) internal view {
922 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3));
923 | }
924 |
925 | function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
926 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
927 | }
928 |
929 | function log(string memory p0, bool p1, string memory p2, bool p3) internal view {
930 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
931 | }
932 |
933 | function log(string memory p0, bool p1, string memory p2, address p3) internal view {
934 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
935 | }
936 |
937 | function log(string memory p0, bool p1, bool p2, uint p3) internal view {
938 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3));
939 | }
940 |
941 | function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
942 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
943 | }
944 |
945 | function log(string memory p0, bool p1, bool p2, bool p3) internal view {
946 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
947 | }
948 |
949 | function log(string memory p0, bool p1, bool p2, address p3) internal view {
950 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
951 | }
952 |
953 | function log(string memory p0, bool p1, address p2, uint p3) internal view {
954 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3));
955 | }
956 |
957 | function log(string memory p0, bool p1, address p2, string memory p3) internal view {
958 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
959 | }
960 |
961 | function log(string memory p0, bool p1, address p2, bool p3) internal view {
962 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
963 | }
964 |
965 | function log(string memory p0, bool p1, address p2, address p3) internal view {
966 | _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
967 | }
968 |
969 | function log(string memory p0, address p1, uint p2, uint p3) internal view {
970 | _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3));
971 | }
972 |
973 | function log(string memory p0, address p1, uint p2, string memory p3) internal view {
974 | _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3));
975 | }
976 |
977 | function log(string memory p0, address p1, uint p2, bool p3) internal view {
978 | _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3));
979 | }
980 |
981 | function log(string memory p0, address p1, uint p2, address p3) internal view {
982 | _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3));
983 | }
984 |
985 | function log(string memory p0, address p1, string memory p2, uint p3) internal view {
986 | _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3));
987 | }
988 |
989 | function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
990 | _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
991 | }
992 |
993 | function log(string memory p0, address p1, string memory p2, bool p3) internal view {
994 | _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
995 | }
996 |
997 | function log(string memory p0, address p1, string memory p2, address p3) internal view {
998 | _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
999 | }
1000 |
1001 | function log(string memory p0, address p1, bool p2, uint p3) internal view {
1002 | _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3));
1003 | }
1004 |
1005 | function log(string memory p0, address p1, bool p2, string memory p3) internal view {
1006 | _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
1007 | }
1008 |
1009 | function log(string memory p0, address p1, bool p2, bool p3) internal view {
1010 | _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
1011 | }
1012 |
1013 | function log(string memory p0, address p1, bool p2, address p3) internal view {
1014 | _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
1015 | }
1016 |
1017 | function log(string memory p0, address p1, address p2, uint p3) internal view {
1018 | _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3));
1019 | }
1020 |
1021 | function log(string memory p0, address p1, address p2, string memory p3) internal view {
1022 | _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
1023 | }
1024 |
1025 | function log(string memory p0, address p1, address p2, bool p3) internal view {
1026 | _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
1027 | }
1028 |
1029 | function log(string memory p0, address p1, address p2, address p3) internal view {
1030 | _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
1031 | }
1032 |
1033 | function log(bool p0, uint p1, uint p2, uint p3) internal view {
1034 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3));
1035 | }
1036 |
1037 | function log(bool p0, uint p1, uint p2, string memory p3) internal view {
1038 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3));
1039 | }
1040 |
1041 | function log(bool p0, uint p1, uint p2, bool p3) internal view {
1042 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3));
1043 | }
1044 |
1045 | function log(bool p0, uint p1, uint p2, address p3) internal view {
1046 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3));
1047 | }
1048 |
1049 | function log(bool p0, uint p1, string memory p2, uint p3) internal view {
1050 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3));
1051 | }
1052 |
1053 | function log(bool p0, uint p1, string memory p2, string memory p3) internal view {
1054 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3));
1055 | }
1056 |
1057 | function log(bool p0, uint p1, string memory p2, bool p3) internal view {
1058 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3));
1059 | }
1060 |
1061 | function log(bool p0, uint p1, string memory p2, address p3) internal view {
1062 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3));
1063 | }
1064 |
1065 | function log(bool p0, uint p1, bool p2, uint p3) internal view {
1066 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3));
1067 | }
1068 |
1069 | function log(bool p0, uint p1, bool p2, string memory p3) internal view {
1070 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3));
1071 | }
1072 |
1073 | function log(bool p0, uint p1, bool p2, bool p3) internal view {
1074 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3));
1075 | }
1076 |
1077 | function log(bool p0, uint p1, bool p2, address p3) internal view {
1078 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3));
1079 | }
1080 |
1081 | function log(bool p0, uint p1, address p2, uint p3) internal view {
1082 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3));
1083 | }
1084 |
1085 | function log(bool p0, uint p1, address p2, string memory p3) internal view {
1086 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3));
1087 | }
1088 |
1089 | function log(bool p0, uint p1, address p2, bool p3) internal view {
1090 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3));
1091 | }
1092 |
1093 | function log(bool p0, uint p1, address p2, address p3) internal view {
1094 | _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3));
1095 | }
1096 |
1097 | function log(bool p0, string memory p1, uint p2, uint p3) internal view {
1098 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3));
1099 | }
1100 |
1101 | function log(bool p0, string memory p1, uint p2, string memory p3) internal view {
1102 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3));
1103 | }
1104 |
1105 | function log(bool p0, string memory p1, uint p2, bool p3) internal view {
1106 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3));
1107 | }
1108 |
1109 | function log(bool p0, string memory p1, uint p2, address p3) internal view {
1110 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3));
1111 | }
1112 |
1113 | function log(bool p0, string memory p1, string memory p2, uint p3) internal view {
1114 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3));
1115 | }
1116 |
1117 | function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
1118 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
1119 | }
1120 |
1121 | function log(bool p0, string memory p1, string memory p2, bool p3) internal view {
1122 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
1123 | }
1124 |
1125 | function log(bool p0, string memory p1, string memory p2, address p3) internal view {
1126 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
1127 | }
1128 |
1129 | function log(bool p0, string memory p1, bool p2, uint p3) internal view {
1130 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3));
1131 | }
1132 |
1133 | function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
1134 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
1135 | }
1136 |
1137 | function log(bool p0, string memory p1, bool p2, bool p3) internal view {
1138 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
1139 | }
1140 |
1141 | function log(bool p0, string memory p1, bool p2, address p3) internal view {
1142 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
1143 | }
1144 |
1145 | function log(bool p0, string memory p1, address p2, uint p3) internal view {
1146 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3));
1147 | }
1148 |
1149 | function log(bool p0, string memory p1, address p2, string memory p3) internal view {
1150 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
1151 | }
1152 |
1153 | function log(bool p0, string memory p1, address p2, bool p3) internal view {
1154 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
1155 | }
1156 |
1157 | function log(bool p0, string memory p1, address p2, address p3) internal view {
1158 | _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
1159 | }
1160 |
1161 | function log(bool p0, bool p1, uint p2, uint p3) internal view {
1162 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3));
1163 | }
1164 |
1165 | function log(bool p0, bool p1, uint p2, string memory p3) internal view {
1166 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3));
1167 | }
1168 |
1169 | function log(bool p0, bool p1, uint p2, bool p3) internal view {
1170 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3));
1171 | }
1172 |
1173 | function log(bool p0, bool p1, uint p2, address p3) internal view {
1174 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3));
1175 | }
1176 |
1177 | function log(bool p0, bool p1, string memory p2, uint p3) internal view {
1178 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3));
1179 | }
1180 |
1181 | function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
1182 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
1183 | }
1184 |
1185 | function log(bool p0, bool p1, string memory p2, bool p3) internal view {
1186 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
1187 | }
1188 |
1189 | function log(bool p0, bool p1, string memory p2, address p3) internal view {
1190 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
1191 | }
1192 |
1193 | function log(bool p0, bool p1, bool p2, uint p3) internal view {
1194 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3));
1195 | }
1196 |
1197 | function log(bool p0, bool p1, bool p2, string memory p3) internal view {
1198 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
1199 | }
1200 |
1201 | function log(bool p0, bool p1, bool p2, bool p3) internal view {
1202 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
1203 | }
1204 |
1205 | function log(bool p0, bool p1, bool p2, address p3) internal view {
1206 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
1207 | }
1208 |
1209 | function log(bool p0, bool p1, address p2, uint p3) internal view {
1210 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3));
1211 | }
1212 |
1213 | function log(bool p0, bool p1, address p2, string memory p3) internal view {
1214 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
1215 | }
1216 |
1217 | function log(bool p0, bool p1, address p2, bool p3) internal view {
1218 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
1219 | }
1220 |
1221 | function log(bool p0, bool p1, address p2, address p3) internal view {
1222 | _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
1223 | }
1224 |
1225 | function log(bool p0, address p1, uint p2, uint p3) internal view {
1226 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3));
1227 | }
1228 |
1229 | function log(bool p0, address p1, uint p2, string memory p3) internal view {
1230 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3));
1231 | }
1232 |
1233 | function log(bool p0, address p1, uint p2, bool p3) internal view {
1234 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3));
1235 | }
1236 |
1237 | function log(bool p0, address p1, uint p2, address p3) internal view {
1238 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3));
1239 | }
1240 |
1241 | function log(bool p0, address p1, string memory p2, uint p3) internal view {
1242 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3));
1243 | }
1244 |
1245 | function log(bool p0, address p1, string memory p2, string memory p3) internal view {
1246 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
1247 | }
1248 |
1249 | function log(bool p0, address p1, string memory p2, bool p3) internal view {
1250 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
1251 | }
1252 |
1253 | function log(bool p0, address p1, string memory p2, address p3) internal view {
1254 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
1255 | }
1256 |
1257 | function log(bool p0, address p1, bool p2, uint p3) internal view {
1258 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3));
1259 | }
1260 |
1261 | function log(bool p0, address p1, bool p2, string memory p3) internal view {
1262 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
1263 | }
1264 |
1265 | function log(bool p0, address p1, bool p2, bool p3) internal view {
1266 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
1267 | }
1268 |
1269 | function log(bool p0, address p1, bool p2, address p3) internal view {
1270 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
1271 | }
1272 |
1273 | function log(bool p0, address p1, address p2, uint p3) internal view {
1274 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3));
1275 | }
1276 |
1277 | function log(bool p0, address p1, address p2, string memory p3) internal view {
1278 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
1279 | }
1280 |
1281 | function log(bool p0, address p1, address p2, bool p3) internal view {
1282 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
1283 | }
1284 |
1285 | function log(bool p0, address p1, address p2, address p3) internal view {
1286 | _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
1287 | }
1288 |
1289 | function log(address p0, uint p1, uint p2, uint p3) internal view {
1290 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3));
1291 | }
1292 |
1293 | function log(address p0, uint p1, uint p2, string memory p3) internal view {
1294 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3));
1295 | }
1296 |
1297 | function log(address p0, uint p1, uint p2, bool p3) internal view {
1298 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3));
1299 | }
1300 |
1301 | function log(address p0, uint p1, uint p2, address p3) internal view {
1302 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3));
1303 | }
1304 |
1305 | function log(address p0, uint p1, string memory p2, uint p3) internal view {
1306 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3));
1307 | }
1308 |
1309 | function log(address p0, uint p1, string memory p2, string memory p3) internal view {
1310 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3));
1311 | }
1312 |
1313 | function log(address p0, uint p1, string memory p2, bool p3) internal view {
1314 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3));
1315 | }
1316 |
1317 | function log(address p0, uint p1, string memory p2, address p3) internal view {
1318 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3));
1319 | }
1320 |
1321 | function log(address p0, uint p1, bool p2, uint p3) internal view {
1322 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3));
1323 | }
1324 |
1325 | function log(address p0, uint p1, bool p2, string memory p3) internal view {
1326 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3));
1327 | }
1328 |
1329 | function log(address p0, uint p1, bool p2, bool p3) internal view {
1330 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3));
1331 | }
1332 |
1333 | function log(address p0, uint p1, bool p2, address p3) internal view {
1334 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3));
1335 | }
1336 |
1337 | function log(address p0, uint p1, address p2, uint p3) internal view {
1338 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3));
1339 | }
1340 |
1341 | function log(address p0, uint p1, address p2, string memory p3) internal view {
1342 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3));
1343 | }
1344 |
1345 | function log(address p0, uint p1, address p2, bool p3) internal view {
1346 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3));
1347 | }
1348 |
1349 | function log(address p0, uint p1, address p2, address p3) internal view {
1350 | _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3));
1351 | }
1352 |
1353 | function log(address p0, string memory p1, uint p2, uint p3) internal view {
1354 | _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3));
1355 | }
1356 |
1357 | function log(address p0, string memory p1, uint p2, string memory p3) internal view {
1358 | _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3));
1359 | }
1360 |
1361 | function log(address p0, string memory p1, uint p2, bool p3) internal view {
1362 | _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3));
1363 | }
1364 |
1365 | function log(address p0, string memory p1, uint p2, address p3) internal view {
1366 | _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3));
1367 | }
1368 |
1369 | function log(address p0, string memory p1, string memory p2, uint p3) internal view {
1370 | _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3));
1371 | }
1372 |
1373 | function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
1374 | _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
1375 | }
1376 |
1377 | function log(address p0, string memory p1, string memory p2, bool p3) internal view {
1378 | _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
1379 | }
1380 |
1381 | function log(address p0, string memory p1, string memory p2, address p3) internal view {
1382 | _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
1383 | }
1384 |
1385 | function log(address p0, string memory p1, bool p2, uint p3) internal view {
1386 | _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3));
1387 | }
1388 |
1389 | function log(address p0, string memory p1, bool p2, string memory p3) internal view {
1390 | _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
1391 | }
1392 |
1393 | function log(address p0, string memory p1, bool p2, bool p3) internal view {
1394 | _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
1395 | }
1396 |
1397 | function log(address p0, string memory p1, bool p2, address p3) internal view {
1398 | _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
1399 | }
1400 |
1401 | function log(address p0, string memory p1, address p2, uint p3) internal view {
1402 | _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3));
1403 | }
1404 |
1405 | function log(address p0, string memory p1, address p2, string memory p3) internal view {
1406 | _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
1407 | }
1408 |
1409 | function log(address p0, string memory p1, address p2, bool p3) internal view {
1410 | _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
1411 | }
1412 |
1413 | function log(address p0, string memory p1, address p2, address p3) internal view {
1414 | _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
1415 | }
1416 |
1417 | function log(address p0, bool p1, uint p2, uint p3) internal view {
1418 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3));
1419 | }
1420 |
1421 | function log(address p0, bool p1, uint p2, string memory p3) internal view {
1422 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3));
1423 | }
1424 |
1425 | function log(address p0, bool p1, uint p2, bool p3) internal view {
1426 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3));
1427 | }
1428 |
1429 | function log(address p0, bool p1, uint p2, address p3) internal view {
1430 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3));
1431 | }
1432 |
1433 | function log(address p0, bool p1, string memory p2, uint p3) internal view {
1434 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3));
1435 | }
1436 |
1437 | function log(address p0, bool p1, string memory p2, string memory p3) internal view {
1438 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
1439 | }
1440 |
1441 | function log(address p0, bool p1, string memory p2, bool p3) internal view {
1442 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
1443 | }
1444 |
1445 | function log(address p0, bool p1, string memory p2, address p3) internal view {
1446 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
1447 | }
1448 |
1449 | function log(address p0, bool p1, bool p2, uint p3) internal view {
1450 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3));
1451 | }
1452 |
1453 | function log(address p0, bool p1, bool p2, string memory p3) internal view {
1454 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
1455 | }
1456 |
1457 | function log(address p0, bool p1, bool p2, bool p3) internal view {
1458 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
1459 | }
1460 |
1461 | function log(address p0, bool p1, bool p2, address p3) internal view {
1462 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
1463 | }
1464 |
1465 | function log(address p0, bool p1, address p2, uint p3) internal view {
1466 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3));
1467 | }
1468 |
1469 | function log(address p0, bool p1, address p2, string memory p3) internal view {
1470 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
1471 | }
1472 |
1473 | function log(address p0, bool p1, address p2, bool p3) internal view {
1474 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
1475 | }
1476 |
1477 | function log(address p0, bool p1, address p2, address p3) internal view {
1478 | _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
1479 | }
1480 |
1481 | function log(address p0, address p1, uint p2, uint p3) internal view {
1482 | _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3));
1483 | }
1484 |
1485 | function log(address p0, address p1, uint p2, string memory p3) internal view {
1486 | _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3));
1487 | }
1488 |
1489 | function log(address p0, address p1, uint p2, bool p3) internal view {
1490 | _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3));
1491 | }
1492 |
1493 | function log(address p0, address p1, uint p2, address p3) internal view {
1494 | _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3));
1495 | }
1496 |
1497 | function log(address p0, address p1, string memory p2, uint p3) internal view {
1498 | _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3));
1499 | }
1500 |
1501 | function log(address p0, address p1, string memory p2, string memory p3) internal view {
1502 | _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
1503 | }
1504 |
1505 | function log(address p0, address p1, string memory p2, bool p3) internal view {
1506 | _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
1507 | }
1508 |
1509 | function log(address p0, address p1, string memory p2, address p3) internal view {
1510 | _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
1511 | }
1512 |
1513 | function log(address p0, address p1, bool p2, uint p3) internal view {
1514 | _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3));
1515 | }
1516 |
1517 | function log(address p0, address p1, bool p2, string memory p3) internal view {
1518 | _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
1519 | }
1520 |
1521 | function log(address p0, address p1, bool p2, bool p3) internal view {
1522 | _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
1523 | }
1524 |
1525 | function log(address p0, address p1, bool p2, address p3) internal view {
1526 | _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
1527 | }
1528 |
1529 | function log(address p0, address p1, address p2, uint p3) internal view {
1530 | _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3));
1531 | }
1532 |
1533 | function log(address p0, address p1, address p2, string memory p3) internal view {
1534 | _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
1535 | }
1536 |
1537 | function log(address p0, address p1, address p2, bool p3) internal view {
1538 | _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
1539 | }
1540 |
1541 | function log(address p0, address p1, address p2, address p3) internal view {
1542 | _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
1543 | }
1544 |
1545 | }
1546 |
--------------------------------------------------------------------------------
|