Compare commits
1131 Commits
@0x/json-s
...
@0x/contra
Author | SHA1 | Date | |
---|---|---|---|
|
5b7eff217e | ||
|
0a6ead90d9 | ||
|
2fa4ed1fb7 | ||
|
3733a29ee2 | ||
|
62b5eef4a0 | ||
|
377d6367e0 | ||
|
a3b364dbdf | ||
|
5dd55491b8 | ||
|
28aa12691e | ||
|
c1bf2754a8 | ||
|
c388e6d2b8 | ||
|
622fa951ca | ||
|
27fc640a9e | ||
|
4689f20b86 | ||
|
de927d7207 | ||
|
93121892d6 | ||
|
c3a7cbc57d | ||
|
0cfeea7c8c | ||
|
e2df4b355b | ||
|
74ed0f4134 | ||
|
5e39eae84e | ||
|
0ea8669552 | ||
|
1631031fa7 | ||
|
0bcb81d3a9 | ||
|
0ac36cef28 | ||
|
04db7f0fae | ||
|
e39ae0350b | ||
|
d0a0673694 | ||
|
3c62815fe3 | ||
|
37b6858869 | ||
|
641685a41e | ||
|
7ad23ef6dc | ||
|
5f2a7cb78f | ||
|
edb989fbf3 | ||
|
ff0093460d | ||
|
a00e416a19 | ||
|
77a2ca1ddc | ||
|
61a3368826 | ||
|
55e3774480 | ||
|
c6ab380685 | ||
|
d6467d707f | ||
|
0893614859 | ||
|
dc940d692f | ||
|
e83a108c52 | ||
|
bbd4828340 | ||
|
6de3a33f36 | ||
|
06139cbfe5 | ||
|
cb1bfa0f97 | ||
|
b249a50d8f | ||
|
0432212a34 | ||
|
7203ca90cf | ||
|
5da748a062 | ||
|
09afee55ed | ||
|
43b648e7dc | ||
|
89fcbec43b | ||
|
c850046ea0 | ||
|
7dda953bc9 | ||
|
b8f3fa9c8c | ||
|
42e04012df | ||
|
17f0878707 | ||
|
e4bb6a4652 | ||
|
3cdb85606a | ||
|
fd37e88bdb | ||
|
24564b986d | ||
|
a91bc415ed | ||
|
ccdb81ac40 | ||
|
d7f9e3f0a0 | ||
|
5720589515 | ||
|
70508f52a1 | ||
|
b90c3196a3 | ||
|
1dda10b4f3 | ||
|
0fba0b1a1b | ||
|
df4f3d9eac | ||
|
de4916ccb8 | ||
|
b797a45d4a | ||
|
eeb07d76fc | ||
|
0abace337c | ||
|
c6ff77bdd8 | ||
|
492e0ae345 | ||
|
8549252a2c | ||
|
aae32037da | ||
|
46359c098b | ||
|
fc71d87d2b | ||
|
67dfe6030c | ||
|
19e93440b3 | ||
|
0cb5209266 | ||
|
1553b366da | ||
|
d957cd5344 | ||
|
354f7053dc | ||
|
4d5fcf8985 | ||
|
71c9b2f718 | ||
|
79863d830e | ||
|
59ec243c26 | ||
|
5e8da70eae | ||
|
99b6ca5b4f | ||
|
4e4de07e69 | ||
|
1b65efb38c | ||
|
ed0e6181bd | ||
|
4dded13259 | ||
|
c82393d763 | ||
|
2111ea159e | ||
|
c1150824dc | ||
|
c62d862967 | ||
|
1ceb3c9664 | ||
|
4252a760f0 | ||
|
5721b25c3a | ||
|
586a8ba8e7 | ||
|
1ddf1087dd | ||
|
72a56db5ab | ||
|
646e856b51 | ||
|
e62e61bf71 | ||
|
a3eab71908 | ||
|
dbbd0c5c92 | ||
|
dc6d6024dc | ||
|
9d5d0dbe14 | ||
|
febf3489ba | ||
|
cfb200e793 | ||
|
2b7875571d | ||
|
0a1701eac9 | ||
|
bcd20081d3 | ||
|
92150b78fc | ||
|
c31f527116 | ||
|
e68c67a01d | ||
|
ea781b8850 | ||
|
ba7c8d9244 | ||
|
a67b34700e | ||
|
abdf91c691 | ||
|
9b540fd8e5 | ||
|
5ec1ae5f7f | ||
|
bed5b275e4 | ||
|
56af9b2aab | ||
|
01e7850cd3 | ||
|
b399aa25aa | ||
|
0a84ee7488 | ||
|
7c7085c932 | ||
|
bbe9862aa6 | ||
|
7e12ae1bfc | ||
|
080c6d3146 | ||
|
2effc3e267 | ||
|
970e670467 | ||
|
36240de897 | ||
|
e4e1c82ad2 | ||
|
9b521aeef5 | ||
|
1fa93fc8ce | ||
|
12177270df | ||
|
d20ed2247f | ||
|
f7fd9789ba | ||
|
75ba724c28 | ||
|
bc3093e635 | ||
|
5d3d596909 | ||
|
5b4d4d5537 | ||
|
521679c87c | ||
|
2a9e03b61e | ||
|
fb003903c7 | ||
|
fbfb6eb45e | ||
|
58be23ac97 | ||
|
90fcf59a32 | ||
|
e74b24bbdb | ||
|
6b5b8fe8e0 | ||
|
0a5ecec3e2 | ||
|
b6f4c5c7da | ||
|
a6ec2a8c54 | ||
|
2fa8b8d1d0 | ||
|
b786836db6 | ||
|
8e5f0f9c5c | ||
|
99e32869e6 | ||
|
04729c44b4 | ||
|
2a2260de45 | ||
|
a7c3996627 | ||
|
6dbcdad1ff | ||
|
f94bdc496a | ||
|
97369c969c | ||
|
72e68c43e3 | ||
|
473537e6e7 | ||
|
ca3e0b26c6 | ||
|
2716374b25 | ||
|
ace968a4fc | ||
|
e6f3693813 | ||
|
531ed54961 | ||
|
5eb316f5d8 | ||
|
97e21106e5 | ||
|
6e4cb0246c | ||
|
125a940560 | ||
|
a7f847bf3e | ||
|
b3978b641c | ||
|
94dc272335 | ||
|
d456710441 | ||
|
e886ef8c4b | ||
|
86a9375d04 | ||
|
f832e035da | ||
|
5656605355 | ||
|
5c4a992b87 | ||
|
0abf1c71f6 | ||
|
85be2fbf19 | ||
|
69de1d05ef | ||
|
237014e823 | ||
|
85a8c6160f | ||
|
e2535027e9 | ||
|
87d157b805 | ||
|
56d48758d3 | ||
|
abfb358250 | ||
|
657b698e1e | ||
|
8ddf925a8f | ||
|
c8eaa63cce | ||
|
b2edd84b0e | ||
|
bc27ee0deb | ||
|
c5632490f2 | ||
|
89ea7b2a2d | ||
|
b3bcd726b8 | ||
|
293dadc22a | ||
|
040b402b6d | ||
|
5c24596d81 | ||
|
552007cafb | ||
|
d2ef88f638 | ||
|
bce7ae78bc | ||
|
90ee70db23 | ||
|
84c8b83694 | ||
|
112724d881 | ||
|
e2510ed28f | ||
|
768e1d541c | ||
|
a650d695ce | ||
|
0eef07307e | ||
|
d69b3a0244 | ||
|
fa5acd07b0 | ||
|
fa612fe173 | ||
|
e10b30886f | ||
|
441b5ac6f1 | ||
|
96a8762704 | ||
|
09eac39040 | ||
|
b96236cdb3 | ||
|
f6525efe95 | ||
|
9728267eac | ||
|
f097259266 | ||
|
38346a9aae | ||
|
ca0ab38521 | ||
|
d2a4fd5706 | ||
|
afe200c4e1 | ||
|
00f5b94d0a | ||
|
1de92659ee | ||
|
25722d8154 | ||
|
bb4ce9b3ad | ||
|
b524ac7af2 | ||
|
dea6f35b04 | ||
|
f3a2e3b6f3 | ||
|
f91781a060 | ||
|
22fd23643c | ||
|
a1266a3341 | ||
|
34ff7fae9c | ||
|
d45c13bfa8 | ||
|
dccca95c2c | ||
|
fc684ad063 | ||
|
6a0f5f39ee | ||
|
4417c76b13 | ||
|
8799f9bb90 | ||
|
6d673ac942 | ||
|
8d6219296a | ||
|
cb9ec18f96 | ||
|
1883f4d272 | ||
|
93b9c251ed | ||
|
3ad72d96f4 | ||
|
4f977aa51d | ||
|
a2df428afb | ||
|
e45a0ffdbf | ||
|
51355209a2 | ||
|
4b0d01ad72 | ||
|
a655f4b193 | ||
|
7af2c751dc | ||
|
d882133e44 | ||
|
7e7880aea0 | ||
|
18f028fb08 | ||
|
14c97b3ec3 | ||
|
58a382d9b6 | ||
|
2be9b1ff08 | ||
|
1cdd82178f | ||
|
dbf1de2e69 | ||
|
ba986432ec | ||
|
3bb147b0f1 | ||
|
0556defa58 | ||
|
4217d0cd7d | ||
|
5863a29a91 | ||
|
df0de07184 | ||
|
28a5ed6a9a | ||
|
c040ad0850 | ||
|
8007ef6c0b | ||
|
a332c5e5c2 | ||
|
bab7569ed9 | ||
|
16bd0ce7ec | ||
|
61a906e9e7 | ||
|
8c9d48477d | ||
|
9f68ac7bbe | ||
|
4e341582ae | ||
|
37a1271af2 | ||
|
743c4c36eb | ||
|
3f7bd24250 | ||
|
33e41dd500 | ||
|
989b5b0a98 | ||
|
a4ab038aa8 | ||
|
e81f92bffa | ||
|
003075a8a5 | ||
|
b4aca370de | ||
|
c854c99f20 | ||
|
0e0e05e0e0 | ||
|
88595718c3 | ||
|
f104d91595 | ||
|
07c1a0121f | ||
|
67521da5c1 | ||
|
9bd71aeeff | ||
|
59d7efa78a | ||
|
102b7154e0 | ||
|
abbb6793cc | ||
|
7b117081d3 | ||
|
342ecae34d | ||
|
b40551e2df | ||
|
ffa57c3703 | ||
|
630ecb98e1 | ||
|
ae27695d25 | ||
|
45d8b522f4 | ||
|
aa5c2c249d | ||
|
1ae9eedf9f | ||
|
622b9f662e | ||
|
e295eeb893 | ||
|
67df5a433d | ||
|
18e55830b5 | ||
|
7664f6a4fd | ||
|
cf553f2afe | ||
|
6cc0e6d55c | ||
|
a6628cd363 | ||
|
6271133350 | ||
|
55589698cf | ||
|
ee0a226c43 | ||
|
d760b355ec | ||
|
4c9bdcd787 | ||
|
b7a8c871d2 | ||
|
230236d4d7 | ||
|
2372925347 | ||
|
df48539d41 | ||
|
90a1947c88 | ||
|
44d9cc53b8 | ||
|
293e099cb3 | ||
|
e34aa4d859 | ||
|
50110b3725 | ||
|
e5815538e4 | ||
|
4fbc544b16 | ||
|
0aa7cbac92 | ||
|
8b24b7c57c | ||
|
ed4573fe2c | ||
|
7468be8f17 | ||
|
0dcada8e06 | ||
|
b255edc577 | ||
|
4ac1db1247 | ||
|
2c24cff950 | ||
|
2107285a00 | ||
|
095cec4342 | ||
|
53529439c5 | ||
|
3cf9cf98dc | ||
|
43cc7b6626 | ||
|
5defa94902 | ||
|
e0116da559 | ||
|
c385627030 | ||
|
031eb8d6a0 | ||
|
c5f85a365b | ||
|
a6fa15c94a | ||
|
14767f1a51 | ||
|
d34d8cac5d | ||
|
1e0aa55368 | ||
|
bb691aa4ed | ||
|
64e84a3510 | ||
|
62f5c58d83 | ||
|
4cf3172c90 | ||
|
8452c05952 | ||
|
8925317c95 | ||
|
248a3998cf | ||
|
be3142a96a | ||
|
4626921bb6 | ||
|
2593f1b8d7 | ||
|
4e80c395b1 | ||
|
1f59c99532 | ||
|
a77e5a1a12 | ||
|
35f7dd71e9 | ||
|
c4036d7d0f | ||
|
6e0d622a15 | ||
|
0e8f0d1d53 | ||
|
c126d01fe3 | ||
|
6d66476d35 | ||
|
039b95c8c1 | ||
|
30ccddf0d5 | ||
|
024e503657 | ||
|
37e5a8a8b7 | ||
|
592c171557 | ||
|
9df0ae90bc | ||
|
33e06fdf40 | ||
|
cce07acf9a | ||
|
d32f77ebb9 | ||
|
35cb769456 | ||
|
9fdd6e56a7 | ||
|
2a0ba501e0 | ||
|
90d4a2b590 | ||
|
f7581d60da | ||
|
2cc03216bd | ||
|
cd4e679db7 | ||
|
28713bdb38 | ||
|
c0b469fdd9 | ||
|
47db165afc | ||
|
f95401ad33 | ||
|
5209729eb1 | ||
|
31bbb0696c | ||
|
6ab8415198 | ||
|
5a6b538a13 | ||
|
42e63b32e3 | ||
|
072c80f475 | ||
|
fb623cf63b | ||
|
5e4defefb0 | ||
|
8d76053210 | ||
|
b7d8362fb1 | ||
|
73e8563413 | ||
|
312d864936 | ||
|
67caa377a4 | ||
|
8234bd5409 | ||
|
3b8598b54b | ||
|
934d3b5d79 | ||
|
5932589776 | ||
|
19e65965c8 | ||
|
8490c31fb7 | ||
|
f242c4206f | ||
|
88240f6401 | ||
|
7065a098e3 | ||
|
6fc80cd776 | ||
|
4611c65aa3 | ||
|
d6866a6dae | ||
|
68be8ef861 | ||
|
0c298b7be4 | ||
|
6eb8256555 | ||
|
240e3558fa | ||
|
8988650c8b | ||
|
28bad6567b | ||
|
1be948bd55 | ||
|
c2b355c25e | ||
|
d12e881e62 | ||
|
85edc297f6 | ||
|
96d89ddade | ||
|
5b4b4123e5 | ||
|
2a577e0475 | ||
|
6382f98608 | ||
|
a12b9e82f6 | ||
|
5d0e715d9a | ||
|
896c8d17c1 | ||
|
ee4185ab46 | ||
|
7661cfc85e | ||
|
f510f9df99 | ||
|
7cafe396de | ||
|
6bb2ef9238 | ||
|
737d1dc54d | ||
|
9b4d1a1e38 | ||
|
c6815bddac | ||
|
6639201fdb | ||
|
57ac2f28a4 | ||
|
8c5ff663a9 | ||
|
67422db4bd | ||
|
7d5388edee | ||
|
51b1cab72a | ||
|
e3dcb7107b | ||
|
f7ceb4cf58 | ||
|
e53f28c570 | ||
|
5c083ba16b | ||
|
4d5bfb5cc2 | ||
|
2adeed38d8 | ||
|
21a193e516 | ||
|
926fcb296f | ||
|
f6f441cbe6 | ||
|
b9fa158092 | ||
|
210840444d | ||
|
d92e143a7e | ||
|
087469f1f3 | ||
|
b6c8126589 | ||
|
8570616d97 | ||
|
373ebdbe38 | ||
|
a1410409ff | ||
|
32eab3acff | ||
|
d9b5884834 | ||
|
76a4468b85 | ||
|
361dc29338 | ||
|
dbdd2fb7d0 | ||
|
b07892bb48 | ||
|
6d45beccad | ||
|
f0581285d0 | ||
|
04d4e797aa | ||
|
ceddc01985 | ||
|
1955c846f2 | ||
|
1efde6f59b | ||
|
6af0cf87e1 | ||
|
101fd78cb2 | ||
|
91d432aa56 | ||
|
dde2baf204 | ||
|
96cb278cae | ||
|
51777ed61d | ||
|
2b4c557a3f | ||
|
84321c41f3 | ||
|
f9dfecaf13 | ||
|
d1f73da675 | ||
|
94c7bf47db | ||
|
4e8d653f1f | ||
|
c5b63ca441 | ||
|
ea668d1376 | ||
|
086c70bcdc | ||
|
461c7efc26 | ||
|
c145349af0 | ||
|
df445eb53c | ||
|
eadad19cb5 | ||
|
d410c44b07 | ||
|
9fa9a30c4d | ||
|
bdc8f9aa2a | ||
|
6db28c5300 | ||
|
0dc9fc4ef7 | ||
|
41ec26c927 | ||
|
51def6ee6b | ||
|
377b87071a | ||
|
1782418f92 | ||
|
f3f78f63ec | ||
|
a2cb815454 | ||
|
ef200b1ce6 | ||
|
f6c173a97e | ||
|
ef403108fb | ||
|
8a06dccbbf | ||
|
4590d07e7f | ||
|
ba89429aec | ||
|
ee38031696 | ||
|
8948029dd7 | ||
|
e78ddd4d5a | ||
|
f179dc3ca7 | ||
|
166a6c85fd | ||
|
c7c07a7c01 | ||
|
f083cafcc7 | ||
|
fab3a90d5a | ||
|
a04c54b4d8 | ||
|
388c7afb50 | ||
|
51f2711796 | ||
|
907aa7a844 | ||
|
9695be13c3 | ||
|
f452fc5bc7 | ||
|
106df4cdaf | ||
|
ed6d83c0a7 | ||
|
66480ccb1e | ||
|
7a10f03496 | ||
|
64c168eafc | ||
|
44e516ac65 | ||
|
d018f6d9cc | ||
|
d5e15b05fb | ||
|
59fad5845c | ||
|
545101f7a5 | ||
|
6878705676 | ||
|
9697d66b66 | ||
|
9cd859a68a | ||
|
33c6e40b70 | ||
|
e48887bc6f | ||
|
52272cd290 | ||
|
ac1786585e | ||
|
f4a95c295c | ||
|
142d29ba57 | ||
|
d84c740274 | ||
|
1c413e632b | ||
|
9a1d2c055e | ||
|
803086da57 | ||
|
2a242e357f | ||
|
1647400a49 | ||
|
41a8dd3e28 | ||
|
81690d1ce5 | ||
|
f846e2f6e0 | ||
|
bfc8a3ccee | ||
|
daf334a588 | ||
|
4d0c59649e | ||
|
a1737f8d93 | ||
|
455f244ec5 | ||
|
6f7e27bd7f | ||
|
ea57367473 | ||
|
088c471b78 | ||
|
9fda63cf74 | ||
|
4cf900631c | ||
|
fed79b2fde | ||
|
d2e29fb081 | ||
|
b4b1d54e49 | ||
|
a852a4077d | ||
|
1c0bf710a4 | ||
|
f4e9103b6f | ||
|
f8e95ae483 | ||
|
70df5a0a17 | ||
|
79dac62646 | ||
|
5bd185e831 | ||
|
687749460d | ||
|
193cd67d6b | ||
|
8d54772389 | ||
|
ddf3bb7c04 | ||
|
167a3fbc11 | ||
|
2e7d363f2c | ||
|
9e5e1f568b | ||
|
65579c0236 | ||
|
be045dad9b | ||
|
885c22676b | ||
|
723dd2bcde | ||
|
a900593c88 | ||
|
756dc1e95e | ||
|
68faaaba5f | ||
|
48fdb567cb | ||
|
bd5a0616c4 | ||
|
0690e68a83 | ||
|
fb99b5ce9d | ||
|
aa8dfa88e1 | ||
|
99941972a3 | ||
|
8a5609718a | ||
|
aeefdeaef7 | ||
|
7b4e536e86 | ||
|
52f733626e | ||
|
c8c68fb75a | ||
|
1364880812 | ||
|
ddc1f34c30 | ||
|
cdca07d829 | ||
|
59b7e25389 | ||
|
87ab8f036c | ||
|
b151b6fe69 | ||
|
8f911206f7 | ||
|
3496725db6 | ||
|
ed588decc6 | ||
|
50e0336018 | ||
|
d07e6cb1d6 | ||
|
ca86f18e7d | ||
|
72e94b3307 | ||
|
7c33c91d59 | ||
|
0f1197c14b | ||
|
4858c0c484 | ||
|
5865b4848d | ||
|
c9af7dc9e5 | ||
|
6e023e6ea3 | ||
|
9176e1f53b | ||
|
0dbe2a91a8 | ||
|
8afac3a92c | ||
|
07a0170f34 | ||
|
1dc67b2874 | ||
|
f09e577885 | ||
|
2c58b8a886 | ||
|
cb53cd05e6 | ||
|
982d59d45d | ||
|
b76a14d51d | ||
|
e8231767ec | ||
|
2b7dabeb6e | ||
|
dde3a0366b | ||
|
8e071db074 | ||
|
93422eab55 | ||
|
74e07b63de | ||
|
7dd0b3a5da | ||
|
b59f20482e | ||
|
98aa7a2c54 | ||
|
7527c61af5 | ||
|
bc6492e352 | ||
|
5c4a2461b8 | ||
|
183edee4ac | ||
|
c513082071 | ||
|
23a6dfac3c | ||
|
e368106932 | ||
|
785981ce58 | ||
|
60bbb9b520 | ||
|
fb81570678 | ||
|
56b82bbc8b | ||
|
05217bb1a2 | ||
|
075fa315e7 | ||
|
fc5f0c9863 | ||
|
13e89d027c | ||
|
ea8f35b743 | ||
|
9365a3bc75 | ||
|
363095f2fe | ||
|
b57b6c04cc | ||
|
e1d77d6e10 | ||
|
da51f6e56f | ||
|
5d0f82c3c6 | ||
|
1878a0c4b0 | ||
|
b538fabdef | ||
|
01716e0d51 | ||
|
7cd3f3cead | ||
|
9d9b5edc9c | ||
|
09a0ca659e | ||
|
1d189d112e | ||
|
829b7cb712 | ||
|
fb8267d85e | ||
|
d842078997 | ||
|
7f574949a4 | ||
|
caeb59a9ae | ||
|
ea95de7d9d | ||
|
52f2ee6e79 | ||
|
ad3d20b342 | ||
|
4fa4f13813 | ||
|
f5f01c0c3e | ||
|
3b9e8e669f | ||
|
99d90bb665 | ||
|
9d8c423b98 | ||
|
d24b2a5a69 | ||
|
aa63632fff | ||
|
d86f5c4fbd | ||
|
0a69752d20 | ||
|
f6ebdd1a3f | ||
|
e2f222b08f | ||
|
50924d62cb | ||
|
da5e8b09d9 | ||
|
fff1e2cfa7 | ||
|
1544e5ed9f | ||
|
4912affbe8 | ||
|
c52ab47185 | ||
|
f082a3f768 | ||
|
27c229a146 | ||
|
43c2b81604 | ||
|
2a133f2c55 | ||
|
4570bc2729 | ||
|
8702a35467 | ||
|
07f80500fa | ||
|
97fc4257a0 | ||
|
25f1b7701f | ||
|
6b889aeeed | ||
|
8e0dcb204f | ||
|
0dc000183a | ||
|
90e1028d2f | ||
|
ed3737c1f1 | ||
|
c9dc69bed6 | ||
|
cd7e41bd5b | ||
|
c46d2f8f9d | ||
|
eb1317a59a | ||
|
98325e1cfb | ||
|
356b7df534 | ||
|
2340813149 | ||
|
8923817b2f | ||
|
7aacf1f5a4 | ||
|
405667fa83 | ||
|
0a3162915f | ||
|
8bcbb64a01 | ||
|
ceafe5ed84 | ||
|
f788fea095 | ||
|
88094002d3 | ||
|
e57a5a6f82 | ||
|
d1ceb2e561 | ||
|
ec2bb616e1 | ||
|
bf56a2c7c4 | ||
|
52b9f4ef3b | ||
|
7845fdbd9c | ||
|
6d2da94f8a | ||
|
20deb01e01 | ||
|
3d9fc6c865 | ||
|
1d5473eece | ||
|
4b4db3802a | ||
|
5eeb848974 | ||
|
5df789bd05 | ||
|
74959cf354 | ||
|
39ceff3d6e | ||
|
fa501e9c93 | ||
|
94c90cc49a | ||
|
d8e03b87d6 | ||
|
f06c17cccc | ||
|
ffff1d5fff | ||
|
fa389f18cd | ||
|
7d5aeacb1c | ||
|
0df51c37d1 | ||
|
bb2581612a | ||
|
3844ce9b60 | ||
|
0c5fa5892c | ||
|
b04a9b9296 | ||
|
2bf831132a | ||
|
6e62b108a9 | ||
|
6262e06afd | ||
|
b1f4bb722d | ||
|
c5db8f25d3 | ||
|
965b1ff32f | ||
|
7f7403cf72 | ||
|
088ca6ce7c | ||
|
5df160ffb9 | ||
|
80efe70247 | ||
|
6c4c666d9b | ||
|
1175a18ccc | ||
|
19f662c196 | ||
|
5f7ed71937 | ||
|
b1a73f5c74 | ||
|
ee7d6fb3af | ||
|
286474ca76 | ||
|
5cbe04acab | ||
|
585c789124 | ||
|
8a761ce2bc | ||
|
bc8981cbb2 | ||
|
26c9cd3cb2 | ||
|
25f66f96b6 | ||
|
0948ed7a87 | ||
|
bc64c9566c | ||
|
d068956b69 | ||
|
1e5bc143be | ||
|
ec72a4b68c | ||
|
1f4af537c0 | ||
|
91c4191985 | ||
|
1d6e66d937 | ||
|
79d31895fb | ||
|
1d4d254496 | ||
|
528d882ec4 | ||
|
2471d4098f | ||
|
33b36eaf07 | ||
|
27bf0d8a16 | ||
|
b5372ade3c | ||
|
1b7c9b0775 | ||
|
a4d9434290 | ||
|
e001988dbe | ||
|
54c9709bf0 | ||
|
cc0fb833fe | ||
|
96ebad7568 | ||
|
3fb74be4ba | ||
|
86acca5e1c | ||
|
cb2b45bf04 | ||
|
3652b8270a | ||
|
0a05ef36a6 | ||
|
11c864e20d | ||
|
6e54514013 | ||
|
e18be3160e | ||
|
6ef5f28f81 | ||
|
beffcd990c | ||
|
c622498e50 | ||
|
d56df4fdaf | ||
|
7226944dfd | ||
|
7aee687e6b | ||
|
4138c580bc | ||
|
a3f12cd4de | ||
|
a208cba4e8 | ||
|
8d0b6702c0 | ||
|
9abd1b79e1 | ||
|
bd725eee86 | ||
|
88c18bd2e6 | ||
|
9dc32c2bca | ||
|
bdd287559c | ||
|
194f785939 | ||
|
086568bddf | ||
|
3506c0e501 | ||
|
93eb31f7a0 | ||
|
934117bfe4 | ||
|
7c33f94836 | ||
|
74d0eb40c5 | ||
|
23987c0fa1 | ||
|
cc1b71651d | ||
|
5e1892f383 | ||
|
93d1f2255e | ||
|
727ced0684 | ||
|
0ff13edb58 | ||
|
0341ced3f3 | ||
|
4f6c95b0ca | ||
|
c4ee6836fa | ||
|
55ed406746 | ||
|
f93e77e77c | ||
|
3ac6da7db1 | ||
|
3e93442a43 | ||
|
a617c801bc | ||
|
7d9ab27b9d | ||
|
c686c241c0 | ||
|
a1889e2a23 | ||
|
37a1483359 | ||
|
80811c9cca | ||
|
14d342c3e0 | ||
|
394105b860 | ||
|
1752aa63da | ||
|
9636fd1b76 | ||
|
16f69ad718 | ||
|
03ca825639 | ||
|
c995586063 | ||
|
8dd738629a | ||
|
701ea77a79 | ||
|
b68f3eb772 | ||
|
47e8bc8e43 | ||
|
eb137cf576 | ||
|
f88ff698a4 | ||
|
49a1f84e16 | ||
|
23675b4901 | ||
|
950c56d7b8 | ||
|
4b166828b8 | ||
|
c1698aa634 | ||
|
ae6f7cc454 | ||
|
506c736d4f | ||
|
0dbb866918 | ||
|
e82f807d7c | ||
|
b586ecdf92 | ||
|
ff8029402d | ||
|
92361ae811 | ||
|
cba8dc8a75 | ||
|
ef1e5eacbd | ||
|
7ba47c47bb | ||
|
f8f3a3b3cc | ||
|
b6e79fd9e0 | ||
|
b39f511755 | ||
|
43d1f61d28 | ||
|
37e3f481dd | ||
|
5acf053f8b | ||
|
b3038787ea | ||
|
b9305f6ab7 | ||
|
21cbf05362 | ||
|
a3718803a0 | ||
|
6742142ca5 | ||
|
b7e06a2282 | ||
|
4c65bbbb8f | ||
|
105da3f814 | ||
|
4a5b72a5ab | ||
|
2d6c46b83c | ||
|
6f5787b2c4 | ||
|
f96711bac3 | ||
|
ddd246a945 | ||
|
d14d38dabd | ||
|
3ca876c574 | ||
|
6d2f4b91a9 | ||
|
6739261a7e | ||
|
72c45d9ea9 | ||
|
75df8a0e8b | ||
|
f3c28afedd | ||
|
80ab797d3a | ||
|
d6dff5f86a | ||
|
4a715c30fd | ||
|
65bb8bdb5e | ||
|
5237e9c2ed | ||
|
6bab2f70b9 | ||
|
a0a41b1b5d | ||
|
f07dc5ae6d | ||
|
8cb6c2b51b | ||
|
1f87bd8cf6 | ||
|
a2aeca7b66 | ||
|
e394c4fe1d | ||
|
5c655eeda7 | ||
|
d932448563 | ||
|
7f782b6af0 | ||
|
a3f4264790 | ||
|
b818a62d74 | ||
|
e69cdfb7b5 | ||
|
45da317e15 | ||
|
c21cf55b86 | ||
|
2dfdc19c9e | ||
|
012134001a | ||
|
0f869b0545 | ||
|
774971c98c | ||
|
25b6e7092f | ||
|
62412b8551 | ||
|
374d513090 | ||
|
a72463dbdb | ||
|
b159d4e0ec | ||
|
1402a3dfae | ||
|
64865bc10f | ||
|
ef00ac6f51 | ||
|
7a7c66b0ec | ||
|
0166c29625 | ||
|
9c35d53694 | ||
|
8701f9a7b0 | ||
|
427c2cd164 | ||
|
8c0dfc1936 | ||
|
392e89fcbb | ||
|
44c1947740 | ||
|
5719eb28f7 | ||
|
ce7027d11f | ||
|
3ba98e2192 | ||
|
1ae3592e45 | ||
|
dc04d025af | ||
|
5262d3b1f2 | ||
|
7d9afce13b | ||
|
c99b71f354 | ||
|
0133bec07d | ||
|
bd7bde9bb0 | ||
|
a6e5d126c3 | ||
|
8e7ea4695b | ||
|
cc5ea80aa3 | ||
|
d1026a64ba | ||
|
dda44500c5 | ||
|
7b81bd831f | ||
|
44312478fa | ||
|
92f56c63ac | ||
|
3d69063bf6 | ||
|
4e03c754e7 | ||
|
87eaa91410 | ||
|
8f5c92b143 | ||
|
77cc1a95bb | ||
|
27cb0386a3 | ||
|
42d6284cf7 | ||
|
893e9f2731 | ||
|
7a6339ae38 | ||
|
fbb27b1fb2 | ||
|
7f8dc8bb1b | ||
|
c47b42d7c1 | ||
|
3bdcf7857f | ||
|
80a25e4b38 | ||
|
4d7e5b4e5d | ||
|
659ae0dcca | ||
|
7a52168cd8 | ||
|
566953d5e1 | ||
|
a849af8a48 | ||
|
cc235aac38 | ||
|
ec24bf8401 | ||
|
9ebb096025 | ||
|
f8b925c9ad | ||
|
a20d547814 | ||
|
3dcb874e08 | ||
|
6b952c4236 | ||
|
9e1a94266e | ||
|
a9895c55f9 | ||
|
682b0dd8f4 | ||
|
00dbddc1aa | ||
|
b552c2bd0c | ||
|
ae9614ba36 | ||
|
871ec6cfbc | ||
|
3c7dca37f5 | ||
|
8acb25f577 | ||
|
eec40080a0 | ||
|
4da419cf75 | ||
|
5bf7b9b8f3 | ||
|
950dae0437 | ||
|
05ef537de0 | ||
|
68d7ce1968 | ||
|
59eca8d748 | ||
|
06304b30c9 | ||
|
03962352df | ||
|
1c03c9168b | ||
|
b6be92e40b | ||
|
06d4abf1ba | ||
|
9349e50bb4 | ||
|
bf672272ce | ||
|
b9fbb3a725 | ||
|
64d52e2113 | ||
|
e0475ce84e | ||
|
64c5181c14 | ||
|
6f333f2b55 | ||
|
7f77347ea4 | ||
|
9ed30fbcca | ||
|
1fab30ef80 | ||
|
62eba1e820 | ||
|
78703ab370 | ||
|
435d9e47e3 | ||
|
5c12e664a9 | ||
|
46422ff783 | ||
|
3a13286585 | ||
|
c98c8b1ded | ||
|
de0b5772bf | ||
|
dbf62ae205 | ||
|
7962e4050c | ||
|
6bf9889429 | ||
|
7f8b9ef1f7 | ||
|
e91fffd005 | ||
|
7314fd7252 | ||
|
247a69aaec | ||
|
d78ac3f157 | ||
|
315584ef51 | ||
|
57e539ed41 | ||
|
db1babd5be | ||
|
bb63c5c86f | ||
|
82d6f2150b | ||
|
5f177108d1 | ||
|
46aa446a61 | ||
|
0883f7087b | ||
|
e782262572 | ||
|
2ba14d656e | ||
|
0c2848c418 | ||
|
47ef28f88f | ||
|
e81bd1b7f0 | ||
|
929eb45699 | ||
|
4456ba0f6a | ||
|
d6329a83d5 | ||
|
203baa4541 | ||
|
e13406cbf4 | ||
|
df213ac0d5 | ||
|
4d7db045e9 | ||
|
849b744185 | ||
|
7161e8fed9 | ||
|
1105d76861 | ||
|
9b6d738ab1 | ||
|
d586c1f67a | ||
|
fff4dd7e94 | ||
|
c2d9585150 | ||
|
3586dde480 | ||
|
d6b92e5786 | ||
|
ab24dcc290 | ||
|
189920eab9 | ||
|
83499176d9 | ||
|
5294c31997 | ||
|
b461147389 | ||
|
1d0d4ca147 | ||
|
2103d5c3ed | ||
|
a21bca7cf4 | ||
|
200da7d22c | ||
|
a114cf5c2e | ||
|
4bc5881e9a | ||
|
a9d413728e | ||
|
e10d34cdfc | ||
|
96b9ffc847 | ||
|
9d850cea14 | ||
|
0e7329bcec | ||
|
b564f090f9 | ||
|
ec099dd009 | ||
|
0577a0dbc5 | ||
|
1bba985124 | ||
|
8bcb5b00ba | ||
|
d0fa615f32 | ||
|
ef6cffd9d9 | ||
|
aa4234a38c | ||
|
9b794c00ea | ||
|
03289293c3 | ||
|
0736ba7159 | ||
|
44ac385e8b | ||
|
512b483b6f | ||
|
5a9755da9b | ||
|
be39c5ba99 | ||
|
0c5b645e86 | ||
|
23bfad6c40 | ||
|
850c441c70 | ||
|
dc434bdff0 | ||
|
0afd490aec | ||
|
c8520c45cb | ||
|
ec6b47ded0 | ||
|
36d94b894a | ||
|
a18a11da92 | ||
|
4bad973877 | ||
|
38e12c2405 | ||
|
f9a7cc94e1 | ||
|
3382077768 | ||
|
b9cbc87882 | ||
|
d05d5ac10d | ||
|
a1fe30e210 | ||
|
56ca19dc9b | ||
|
969674a5ce | ||
|
d2a418b368 | ||
|
081859f334 | ||
|
1cc06dd9e6 | ||
|
d642082058 | ||
|
d3aebd0b79 | ||
|
7b90f095ff | ||
|
df6c1ae059 | ||
|
5578c70cd6 | ||
|
3e2c93f5a0 | ||
|
471a4e981a | ||
|
6b4112527f | ||
|
3a9f8a7296 | ||
|
bbb3e5afcc | ||
|
9b0020a884 | ||
|
ec12e46e3f |
@@ -188,9 +188,7 @@ jobs:
|
||||
working_directory: ~/repo
|
||||
docker:
|
||||
- image: circleci/python
|
||||
- image: 0xorg/ganache-cli
|
||||
command: |
|
||||
ganache-cli --gasLimit 10000000 --noVMErrorsOnRPCResponse --db /snapshot --noVMErrorsOnRPCResponse -p 8545 --networkId 50 -m "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
||||
- image: 0xorg/ganache-cli:2.2.2
|
||||
- image: 0xorg/launch-kit-ci
|
||||
command: |
|
||||
yarn start:ts -p 3000:3000
|
||||
@@ -200,16 +198,27 @@ jobs:
|
||||
- run: sudo chown -R circleci:circleci /usr/local/lib/python3.7/site-packages
|
||||
- restore_cache:
|
||||
key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run:
|
||||
command: |
|
||||
cd python-packages/json_schemas
|
||||
python -m ensurepip
|
||||
python -m pip install .[dev]
|
||||
# HACK! installing the package should do the following
|
||||
# copy for us, but it's not working in CircleCI for some
|
||||
# reason. Zendesk support ticket raised (#43979) with
|
||||
# CircleCI.
|
||||
mkdir /usr/local/lib/python3.7/site-packages/zero_ex/json_schemas/schemas
|
||||
cp -R src/zero_ex/json_schemas/schemas/* /usr/local/lib/python3.7/site-packages/zero_ex/json_schemas/schemas
|
||||
- run:
|
||||
command: |
|
||||
cd python-packages/order_utils
|
||||
python -m ensurepip
|
||||
python -m pip install -e .[dev]
|
||||
python -m pip install .[dev]
|
||||
- run:
|
||||
command: |
|
||||
cd python-packages/sra_client
|
||||
python -m ensurepip
|
||||
python -m pip install -e .
|
||||
python -m pip install .[dev]
|
||||
- save_cache:
|
||||
key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
@@ -219,6 +228,10 @@ jobs:
|
||||
- '.mypy_cache'
|
||||
- '.pytest_cache'
|
||||
- '.tox'
|
||||
- run:
|
||||
command: |
|
||||
cd python-packages/json_schemas
|
||||
coverage run setup.py test
|
||||
- run:
|
||||
command: |
|
||||
cd python-packages/order_utils
|
||||
@@ -227,6 +240,10 @@ jobs:
|
||||
command: |
|
||||
cd python-packages/sra_client
|
||||
coverage run setup.py test
|
||||
- save_cache:
|
||||
key: coverage-python-json-schemas-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/python-packages/json_schemas/.coverage
|
||||
- save_cache:
|
||||
key: coverage-python-order-utils-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
@@ -249,7 +266,7 @@ jobs:
|
||||
command: |
|
||||
cd python-packages/order_utils
|
||||
python -m ensurepip
|
||||
python -m pip install -e .[dev]
|
||||
python -m pip install .
|
||||
- save_cache:
|
||||
key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
@@ -273,16 +290,25 @@ jobs:
|
||||
- run: sudo chown -R circleci:circleci /usr/local/lib/python3.7/site-packages
|
||||
- restore_cache:
|
||||
key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run:
|
||||
command: |
|
||||
cd python-packages/json_schemas
|
||||
python -m ensurepip
|
||||
python -m pip install .[dev]
|
||||
- run:
|
||||
command: |
|
||||
cd python-packages/order_utils
|
||||
python -m ensurepip
|
||||
python -m pip install -e .[dev]
|
||||
python -m pip install .[dev]
|
||||
- save_cache:
|
||||
key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- '/usr/local/bin'
|
||||
- '/usr/local/lib/python3.7/site-packages'
|
||||
- run:
|
||||
command: |
|
||||
cd python-packages/json_schemas
|
||||
python setup.py lint
|
||||
- run:
|
||||
command: |
|
||||
cd python-packages/order_utils
|
||||
@@ -355,6 +381,9 @@ jobs:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-python-json-schemas-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-python-order-utils-{{ .Environment.CIRCLE_SHA1 }}
|
||||
|
2
.github/stale.yml
vendored
2
.github/stale.yml
vendored
@@ -1,7 +1,7 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 30
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
daysUntilClose: 30
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
|
@@ -20,10 +20,13 @@ lib
|
||||
/packages/contract-artifacts/artifacts
|
||||
/python-packages/order_utils/src/zero_ex/contract_artifacts/artifacts
|
||||
/packages/json-schemas/schemas
|
||||
/python-packages/order_utils/src/zero_ex/json_schemas/schemas
|
||||
/python-packages/json_schemas/src/zero_ex/json_schemas/schemas
|
||||
/packages/metacoin/src/contract_wrappers
|
||||
/packages/metacoin/artifacts
|
||||
/packages/sra-spec/public/
|
||||
package.json
|
||||
scripts/postpublish_utils.js
|
||||
packages/sol-cov/test/fixtures/artifacts
|
||||
.pytest_cache
|
||||
.mypy_cache
|
||||
.tox
|
||||
|
@@ -79,7 +79,20 @@ If using the Atom text editor, we recommend you install the following packages:
|
||||
* VSCode: [prettier-vscode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
|
||||
* Atom: [prettier-atom](https://atom.io/packages/prettier-atom)
|
||||
|
||||
## Fix `submit-coverage` CI failure
|
||||
## Unenforced coding conventions
|
||||
|
||||
A few of our coding conventions are not yet enforced by the linter/auto-formatter. Be careful to follow these conventions in your PR's.
|
||||
|
||||
1. Unused anonymous function parameters should be named with an underscore + number (e.g \_1, \_2, etc...)
|
||||
1. There should be a new-line between methods in a class and between test cases.
|
||||
1. If a string literal has the same value in two or more places, it should be a single constant referenced in both places.
|
||||
1. Do not import from a project's `index.ts` (e.g import { Token } from '../src';). Always import from the source file itself.
|
||||
1. Generic error variables should be named `err` instead of `e` or `error`.
|
||||
1. If you _must_ cast a variable to any - try to type it back as fast as possible. (e.g., `const cw = ((zeroEx as any)._contractWrappers as ContractWrappers);`). This ensures subsequent code is type-safe.
|
||||
1. Our enum conventions coincide with the recommended Typescript conventions, using capitalized keys, and all-caps snake-case values. Eg `GetStats = 'GET_STATS'`
|
||||
1. All public, exported methods/functions/classes must have associated Javadoc-style comments.
|
||||
|
||||
### Fix `submit-coverage` CI failure
|
||||
|
||||
If you simply fork the repo and then create a PR from it, your PR will fail the `submit-coverage` check on CI. This is because the 0x CircleCI configuration sets the `COVERALLS_REPO_TOKEN` environment variable to the token for `0xProject/0x-monorepo`, but when running the check against your fork the token needs to match your repo's name `your-username/0x-monorepo`.
|
||||
|
||||
|
11
README.md
11
README.md
@@ -1,4 +1,4 @@
|
||||
<img src="https://github.com/0xProject/branding/blob/master/0x_Black_CMYK.png" width="200px" >
|
||||
<img src="https://github.com/0xProject/branding/blob/master/0x%20Logo/PNG/0x-Logo-Black.png" width="150px" >
|
||||
|
||||
---
|
||||
|
||||
@@ -24,10 +24,11 @@ Visit our [developer portal](https://0xproject.com/docs/order-utils) for a compr
|
||||
|
||||
### Python Packages
|
||||
|
||||
| Package | Version | Description |
|
||||
| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| [`0x-order-utils`](/python-packages/order_utils) | [](https://pypi.org/project/0x-order-utils/) | A set of utilities for generating, parsing, signing and validating 0x orders |
|
||||
| [`0x-sra-client`](/python-packages/sra_client) | [](https://pypi.org/project/0x-sra-client/) | A Python client for interacting with servers conforming to the Standard Relayer API specification |
|
||||
| Package | Version | Description |
|
||||
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| [`0x-json-schemas`](/python-packages/json_schemas) | [](https://pypi.org/project/0x-json-schemas/) | 0x-related JSON schemas |
|
||||
| [`0x-order-utils`](/python-packages/order_utils) | [](https://pypi.org/project/0x-order-utils/) | A set of utilities for generating, parsing, signing and validating 0x orders |
|
||||
| [`0x-sra-client`](/python-packages/sra_client) | [](https://pypi.org/project/0x-sra-client/) | A Python client for interacting with servers conforming to the Standard Relayer API specification |
|
||||
|
||||
### Typescript/Javascript Packages
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
"avoid-tx-origin": "warn",
|
||||
"bracket-align": false,
|
||||
"code-complexity": false,
|
||||
"compiler-fixed": false,
|
||||
"const-name-snakecase": "error",
|
||||
"expression-indent": "error",
|
||||
"function-max-lines": false,
|
||||
|
20
contracts/examples/CHANGELOG.json
Normal file
20
contracts/examples/CHANGELOG.json
Normal file
@@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547040760,
|
||||
"version": "1.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1544741676,
|
||||
"version": "1.0.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
14
contracts/examples/CHANGELOG.md
Normal file
14
contracts/examples/CHANGELOG.md
Normal file
@@ -0,0 +1,14 @@
|
||||
<!--
|
||||
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
|
||||
Edit the package's CHANGELOG.json file only.
|
||||
-->
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.3 - _January 9, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.2 - _December 13, 2018_
|
||||
|
||||
* Dependencies updated
|
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@0x/contracts-examples",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -14,7 +13,8 @@
|
||||
"build": "yarn pre_build && tsc -b",
|
||||
"build:ci": "yarn build",
|
||||
"pre_build": "run-s compile generate_contract_wrappers",
|
||||
"compile": "sol-compiler --contracts-dir contracts",
|
||||
"compile": "sol-compiler",
|
||||
"watch": "sol-compiler -w",
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
@@ -33,12 +33,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/examples/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.19",
|
||||
"@0x/contracts-test-utils": "^1.0.2",
|
||||
"@0x/dev-utils": "^1.0.21",
|
||||
"@0x/sol-compiler": "^1.1.16",
|
||||
"@0x/sol-cov": "^2.1.16",
|
||||
"@0x/subproviders": "^2.1.8",
|
||||
"@0x/abi-gen": "^1.0.20",
|
||||
"@0x/contracts-test-utils": "^1.0.3",
|
||||
"@0x/dev-utils": "^1.0.22",
|
||||
"@0x/sol-compiler": "^2.0.0",
|
||||
"@0x/sol-cov": "^2.1.17",
|
||||
"@0x/subproviders": "^2.1.9",
|
||||
"@0x/tslint-config": "^2.0.0",
|
||||
"@types/bn.js": "^4.11.0",
|
||||
"@types/lodash": "4.14.104",
|
||||
@@ -53,24 +53,23 @@
|
||||
"mocha": "^4.1.0",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"shx": "^0.2.2",
|
||||
"solc": "^0.4.24",
|
||||
"solhint": "^1.4.1",
|
||||
"tslint": "5.11.0",
|
||||
"typescript": "3.0.1",
|
||||
"yargs": "^10.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.10",
|
||||
"@0x/contracts-interfaces": "^1.0.1",
|
||||
"@0x/contracts-libs": "^1.0.1",
|
||||
"@0x/contracts-multisig": "^1.0.1",
|
||||
"@0x/contracts-tokens": "^1.0.1",
|
||||
"@0x/contracts-utils": "^1.0.1",
|
||||
"@0x/order-utils": "^3.0.7",
|
||||
"@0x/types": "^1.4.1",
|
||||
"@0x/base-contract": "^3.0.11",
|
||||
"@0x/contracts-interfaces": "^1.0.3",
|
||||
"@0x/contracts-libs": "^1.0.3",
|
||||
"@0x/contracts-multisig": "^1.0.3",
|
||||
"@0x/contracts-tokens": "^1.0.3",
|
||||
"@0x/contracts-utils": "^1.0.3",
|
||||
"@0x/order-utils": "^3.1.0",
|
||||
"@0x/types": "^1.5.0",
|
||||
"@0x/typescript-typings": "^3.0.6",
|
||||
"@0x/utils": "^2.0.8",
|
||||
"@0x/web3-wrapper": "^3.2.1",
|
||||
"@0x/utils": "^2.1.1",
|
||||
"@0x/web3-wrapper": "^3.2.2",
|
||||
"@types/js-combinatorics": "^0.5.29",
|
||||
"bn.js": "^4.11.8",
|
||||
"ethereum-types": "^1.1.4",
|
||||
|
38
contracts/extensions/CHANGELOG.json
Normal file
38
contracts/extensions/CHANGELOG.json
Normal file
@@ -0,0 +1,38 @@
|
||||
[
|
||||
{
|
||||
"version": "1.2.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Added Dutch Auction Wrapper",
|
||||
"pr": 1465
|
||||
}
|
||||
],
|
||||
"timestamp": 1547040760
|
||||
},
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Added Balance Threshold Filter",
|
||||
"pr": 1383
|
||||
},
|
||||
{
|
||||
"note": "Add OrderMatcher",
|
||||
"pr": 1117
|
||||
},
|
||||
{
|
||||
"note": "Add OrderValidator",
|
||||
"pr": 1464
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1544741676,
|
||||
"version": "1.0.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
20
contracts/extensions/CHANGELOG.md
Normal file
20
contracts/extensions/CHANGELOG.md
Normal file
@@ -0,0 +1,20 @@
|
||||
<!--
|
||||
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
|
||||
Edit the package's CHANGELOG.json file only.
|
||||
-->
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.2.0 - _January 9, 2019_
|
||||
|
||||
* Added Dutch Auction Wrapper (#1465)
|
||||
|
||||
## v1.1.0 - _Invalid date_
|
||||
|
||||
* Added Balance Threshold Filter (#1383)
|
||||
* Add OrderMatcher (#1117)
|
||||
* Add OrderValidator (#1464)
|
||||
|
||||
## v1.0.2 - _December 13, 2018_
|
||||
|
||||
* Dependencies updated
|
31
contracts/extensions/DEPLOYS.json
Normal file
31
contracts/extensions/DEPLOYS.json
Normal file
@@ -0,0 +1,31 @@
|
||||
[
|
||||
{
|
||||
"name": "Forwarder",
|
||||
"version": "1.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Round up when calculating remaining amounts in marketBuy functions",
|
||||
"pr": 1162,
|
||||
"networks": {
|
||||
"1": "0x5468a1dc173652ee28d249c271fa9933144746b1",
|
||||
"3": "0x2240dab907db71e64d3e0dba4800c83b5c502d4e",
|
||||
"42": "0x17992e4ffb22730138e4b62aaa6367fa9d3699a6"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Forwarder",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x7afc2d5107af94c462a194d2c21b5bdd238709d6",
|
||||
"3": "0x3983e204b12b3c02fb0638caf2cd406a62e0ead3",
|
||||
"42": "0xd85e2fa7e7e252b27b01bf0d65c946959d2f45b8"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@@ -18,5 +18,5 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"contracts": ["DutchAuction", "Forwarder"]
|
||||
"contracts": ["BalanceThresholdFilter", "DutchAuction", "Forwarder", "OrderMatcher", "OrderValidator"]
|
||||
}
|
||||
|
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
|
||||
import "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol";
|
||||
import "./interfaces/IThresholdAsset.sol";
|
||||
import "./MixinBalanceThresholdFilterCore.sol";
|
||||
|
||||
|
||||
contract BalanceThresholdFilter is
|
||||
MixinBalanceThresholdFilterCore
|
||||
{
|
||||
|
||||
/// @dev Constructs BalanceThresholdFilter.
|
||||
/// @param exchange Address of 0x exchange.
|
||||
/// @param thresholdAsset The asset that must be held by makers/takers.
|
||||
/// @param balanceThreshold The minimum balance of `thresholdAsset` that must be held by makers/takers.
|
||||
constructor(
|
||||
address exchange,
|
||||
address thresholdAsset,
|
||||
uint256 balanceThreshold
|
||||
)
|
||||
public
|
||||
{
|
||||
EXCHANGE = IExchange(exchange);
|
||||
THRESHOLD_ASSET = IThresholdAsset(thresholdAsset);
|
||||
BALANCE_THRESHOLD = balanceThreshold;
|
||||
}
|
||||
}
|
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-libs/contracts/libs/LibExchangeSelectors.sol";
|
||||
import "@0x/contracts-libs/contracts/libs/LibOrder.sol";
|
||||
import "./mixins/MBalanceThresholdFilterCore.sol";
|
||||
import "./MixinExchangeCalldata.sol";
|
||||
|
||||
|
||||
contract MixinBalanceThresholdFilterCore is
|
||||
MBalanceThresholdFilterCore,
|
||||
MixinExchangeCalldata,
|
||||
LibOrder,
|
||||
LibExchangeSelectors
|
||||
{
|
||||
|
||||
/// @dev Executes an Exchange transaction iff the maker and taker meet
|
||||
/// the hold at least `BALANCE_THRESHOLD` of the asset `THRESHOLD_ASSET` OR
|
||||
/// the exchange function is a cancellation.
|
||||
/// Supported Exchange functions:
|
||||
/// batchFillOrders
|
||||
/// batchFillOrdersNoThrow
|
||||
/// batchFillOrKillOrders
|
||||
/// fillOrder
|
||||
/// fillOrderNoThrow
|
||||
/// fillOrKillOrder
|
||||
/// marketBuyOrders
|
||||
/// marketBuyOrdersNoThrow
|
||||
/// marketSellOrders
|
||||
/// marketSellOrdersNoThrow
|
||||
/// matchOrders
|
||||
/// cancelOrder
|
||||
/// batchCancelOrders
|
||||
/// cancelOrdersUpTo
|
||||
/// Trying to call any other exchange function will throw.
|
||||
/// @param salt Arbitrary number to ensure uniqueness of transaction hash.
|
||||
/// @param signerAddress Address of transaction signer.
|
||||
/// @param signedExchangeTransaction AbiV2 encoded calldata.
|
||||
/// @param signature Proof of signer transaction by signer.
|
||||
function executeTransaction(
|
||||
uint256 salt,
|
||||
address signerAddress,
|
||||
bytes signedExchangeTransaction,
|
||||
bytes signature
|
||||
)
|
||||
external
|
||||
{
|
||||
// Get accounts whose balances must be validated
|
||||
address[] memory addressesToValidate = getAddressesToValidate(signerAddress);
|
||||
|
||||
// Validate account balances
|
||||
uint256 balanceThreshold = BALANCE_THRESHOLD;
|
||||
IThresholdAsset thresholdAsset = THRESHOLD_ASSET;
|
||||
for (uint256 i = 0; i < addressesToValidate.length; ++i) {
|
||||
uint256 addressBalance = thresholdAsset.balanceOf(addressesToValidate[i]);
|
||||
require(
|
||||
addressBalance >= balanceThreshold,
|
||||
"AT_LEAST_ONE_ADDRESS_DOES_NOT_MEET_BALANCE_THRESHOLD"
|
||||
);
|
||||
}
|
||||
emit ValidatedAddresses(addressesToValidate);
|
||||
|
||||
// All addresses are valid. Execute exchange function.
|
||||
EXCHANGE.executeTransaction(
|
||||
salt,
|
||||
signerAddress,
|
||||
signedExchangeTransaction,
|
||||
signature
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Constructs an array of addresses to be validated.
|
||||
/// Addresses depend on which Exchange function is to be called
|
||||
/// (defined by `signedExchangeTransaction` above).
|
||||
/// @param signerAddress Address of transaction signer.
|
||||
/// @return addressesToValidate Array of addresses to validate.
|
||||
function getAddressesToValidate(address signerAddress)
|
||||
internal pure
|
||||
returns (address[] memory addressesToValidate)
|
||||
{
|
||||
bytes4 exchangeFunctionSelector = bytes4(exchangeCalldataload(0));
|
||||
// solhint-disable expression-indent
|
||||
if (
|
||||
exchangeFunctionSelector == BATCH_FILL_ORDERS_SELECTOR ||
|
||||
exchangeFunctionSelector == BATCH_FILL_ORDERS_NO_THROW_SELECTOR ||
|
||||
exchangeFunctionSelector == BATCH_FILL_OR_KILL_ORDERS_SELECTOR ||
|
||||
exchangeFunctionSelector == MARKET_BUY_ORDERS_SELECTOR ||
|
||||
exchangeFunctionSelector == MARKET_BUY_ORDERS_NO_THROW_SELECTOR ||
|
||||
exchangeFunctionSelector == MARKET_SELL_ORDERS_SELECTOR ||
|
||||
exchangeFunctionSelector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR
|
||||
) {
|
||||
addressesToValidate = loadMakerAddressesFromOrderArray(0);
|
||||
addressesToValidate = addressesToValidate.append(signerAddress);
|
||||
} else if (
|
||||
exchangeFunctionSelector == FILL_ORDER_SELECTOR ||
|
||||
exchangeFunctionSelector == FILL_ORDER_NO_THROW_SELECTOR ||
|
||||
exchangeFunctionSelector == FILL_OR_KILL_ORDER_SELECTOR
|
||||
) {
|
||||
address makerAddress = loadMakerAddressFromOrder(0);
|
||||
addressesToValidate = addressesToValidate.append(makerAddress);
|
||||
addressesToValidate = addressesToValidate.append(signerAddress);
|
||||
} else if (exchangeFunctionSelector == MATCH_ORDERS_SELECTOR) {
|
||||
address leftMakerAddress = loadMakerAddressFromOrder(0);
|
||||
addressesToValidate = addressesToValidate.append(leftMakerAddress);
|
||||
address rightMakerAddress = loadMakerAddressFromOrder(1);
|
||||
addressesToValidate = addressesToValidate.append(rightMakerAddress);
|
||||
addressesToValidate = addressesToValidate.append(signerAddress);
|
||||
} else if (
|
||||
exchangeFunctionSelector != CANCEL_ORDER_SELECTOR &&
|
||||
exchangeFunctionSelector != BATCH_CANCEL_ORDERS_SELECTOR &&
|
||||
exchangeFunctionSelector != CANCEL_ORDERS_UP_TO_SELECTOR
|
||||
) {
|
||||
revert("INVALID_OR_BLOCKED_EXCHANGE_SELECTOR");
|
||||
}
|
||||
// solhint-enable expression-indent
|
||||
return addressesToValidate;
|
||||
}
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "./mixins/MExchangeCalldata.sol";
|
||||
import "@0x/contracts-libs/contracts/libs/LibAddressArray.sol";
|
||||
|
||||
|
||||
contract MixinExchangeCalldata is
|
||||
MExchangeCalldata
|
||||
{
|
||||
|
||||
using LibAddressArray for address[];
|
||||
|
||||
/// @dev Emulates the `calldataload` opcode on the embedded Exchange calldata,
|
||||
/// which is accessed through `signedExchangeTransaction`.
|
||||
/// @param offset Offset into the Exchange calldata.
|
||||
/// @return value Corresponding 32 byte value stored at `offset`.
|
||||
function exchangeCalldataload(uint256 offset)
|
||||
internal pure
|
||||
returns (bytes32 value)
|
||||
{
|
||||
assembly {
|
||||
// Pointer to exchange transaction
|
||||
// 0x04 for calldata selector
|
||||
// 0x40 to access `signedExchangeTransaction`, which is the third parameter
|
||||
let exchangeTxPtr := calldataload(0x44)
|
||||
|
||||
// Offset into Exchange calldata
|
||||
// We compute this by adding 0x24 to the `exchangeTxPtr` computed above.
|
||||
// 0x04 for calldata selector
|
||||
// 0x20 for length field of `signedExchangeTransaction`
|
||||
let exchangeCalldataOffset := add(exchangeTxPtr, add(0x24, offset))
|
||||
value := calldataload(exchangeCalldataOffset)
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/// @dev Convenience function that skips the 4 byte selector when loading
|
||||
/// from the embedded Exchange calldata.
|
||||
/// @param offset Offset into the Exchange calldata (minus the 4 byte selector)
|
||||
/// @return value Corresponding 32 byte value stored at `offset` + 4.
|
||||
function loadExchangeData(uint256 offset)
|
||||
internal pure
|
||||
returns (bytes32 value)
|
||||
{
|
||||
value = exchangeCalldataload(offset + 4);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// @dev Extracts the maker address from an order stored in the Exchange calldata
|
||||
/// (which is embedded in `signedExchangeTransaction`).
|
||||
/// @param orderParamIndex Index of the order in the Exchange function's signature.
|
||||
/// @return makerAddress The extracted maker address.
|
||||
function loadMakerAddressFromOrder(uint256 orderParamIndex)
|
||||
internal pure
|
||||
returns (address makerAddress)
|
||||
{
|
||||
uint256 orderOffsetInBytes = orderParamIndex * 32;
|
||||
uint256 orderPtr = uint256(loadExchangeData(orderOffsetInBytes));
|
||||
makerAddress = address(loadExchangeData(orderPtr));
|
||||
return makerAddress;
|
||||
}
|
||||
|
||||
/// @dev Extracts the maker addresses from an array of orders stored in the Exchange calldata
|
||||
/// (which is embedded in `signedExchangeTransaction`).
|
||||
/// @param orderArrayParamIndex Index of the order array in the Exchange function's signature
|
||||
/// @return makerAddresses The extracted maker addresses.
|
||||
function loadMakerAddressesFromOrderArray(uint256 orderArrayParamIndex)
|
||||
internal pure
|
||||
returns (address[] makerAddresses)
|
||||
{
|
||||
uint256 orderArrayOffsetInBytes = orderArrayParamIndex * 32;
|
||||
uint256 orderArrayPtr = uint256(loadExchangeData(orderArrayOffsetInBytes));
|
||||
uint256 orderArrayLength = uint256(loadExchangeData(orderArrayPtr));
|
||||
uint256 orderArrayLengthInBytes = orderArrayLength * 32;
|
||||
uint256 orderArrayElementPtr = orderArrayPtr + 32;
|
||||
uint256 orderArrayElementEndPtr = orderArrayElementPtr + orderArrayLengthInBytes;
|
||||
for (uint orderPtrOffset = orderArrayElementPtr; orderPtrOffset < orderArrayElementEndPtr; orderPtrOffset += 32) {
|
||||
uint256 orderPtr = uint256(loadExchangeData(orderPtrOffset));
|
||||
address makerAddress = address(loadExchangeData(orderPtr + orderArrayElementPtr));
|
||||
makerAddresses = makerAddresses.append(makerAddress);
|
||||
}
|
||||
return makerAddresses;
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract IBalanceThresholdFilterCore {
|
||||
|
||||
/// @dev Executes an Exchange transaction iff the maker and taker meet
|
||||
/// the hold at least `BALANCE_THRESHOLD` of the asset `THRESHOLD_ASSET` OR
|
||||
/// the exchange function is a cancellation.
|
||||
/// Supported Exchange functions:
|
||||
/// - batchFillOrders
|
||||
/// - batchFillOrdersNoThrow
|
||||
/// - batchFillOrKillOrders
|
||||
/// - fillOrder
|
||||
/// - fillOrderNoThrow
|
||||
/// - fillOrKillOrder
|
||||
/// - marketBuyOrders
|
||||
/// - marketBuyOrdersNoThrow
|
||||
/// - marketSellOrders
|
||||
/// - marketSellOrdersNoThrow
|
||||
/// - matchOrders
|
||||
/// - cancelOrder
|
||||
/// - batchCancelOrders
|
||||
/// - cancelOrdersUpTo
|
||||
/// Trying to call any other exchange function will throw.
|
||||
/// @param salt Arbitrary number to ensure uniqueness of transaction hash.
|
||||
/// @param signerAddress Address of transaction signer.
|
||||
/// @param signedExchangeTransaction AbiV2 encoded calldata.
|
||||
/// @param signature Proof of signer transaction by signer.
|
||||
function executeTransaction(
|
||||
uint256 salt,
|
||||
address signerAddress,
|
||||
bytes signedExchangeTransaction,
|
||||
bytes signature
|
||||
)
|
||||
external;
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract IThresholdAsset {
|
||||
|
||||
/// @param _owner The address from which the balance will be retrieved
|
||||
/// @return Balance of owner
|
||||
function balanceOf(address _owner)
|
||||
external
|
||||
view
|
||||
returns (uint256);
|
||||
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol";
|
||||
import "../interfaces/IThresholdAsset.sol";
|
||||
import "../interfaces/IBalanceThresholdFilterCore.sol";
|
||||
|
||||
|
||||
contract MBalanceThresholdFilterCore is
|
||||
IBalanceThresholdFilterCore
|
||||
{
|
||||
|
||||
// Points to 0x exchange contract
|
||||
// solhint-disable var-name-mixedcase
|
||||
IExchange internal EXCHANGE;
|
||||
|
||||
// The asset that must be held by makers/takers
|
||||
IThresholdAsset internal THRESHOLD_ASSET;
|
||||
|
||||
// The minimum balance of `THRESHOLD_ASSET` that must be held by makers/takers
|
||||
uint256 internal BALANCE_THRESHOLD;
|
||||
// solhint-enable var-name-mixedcase
|
||||
|
||||
// Addresses that hold at least `BALANCE_THRESHOLD` of `THRESHOLD_ASSET`
|
||||
event ValidatedAddresses (
|
||||
address[] addresses
|
||||
);
|
||||
|
||||
/// @dev Constructs an array of addresses to be validated.
|
||||
/// Addresses depend on which Exchange function is to be called
|
||||
/// (defined by `signedExchangeTransaction` above).
|
||||
/// @param signerAddress Address of transaction signer.
|
||||
/// @return addressesToValidate Array of addresses to validate.
|
||||
function getAddressesToValidate(address signerAddress)
|
||||
internal pure
|
||||
returns (address[] memory addressesToValidate);
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract MExchangeCalldata {
|
||||
|
||||
/// @dev Emulates the `calldataload` opcode on the embedded Exchange calldata,
|
||||
/// which is accessed through `signedExchangeTransaction`.
|
||||
/// @param offset Offset into the Exchange calldata.
|
||||
/// @return value Corresponding 32 byte value stored at `offset`.
|
||||
function exchangeCalldataload(uint256 offset)
|
||||
internal pure
|
||||
returns (bytes32 value);
|
||||
|
||||
/// @dev Convenience function that skips the 4 byte selector when loading
|
||||
/// from the embedded Exchange calldata.
|
||||
/// @param offset Offset into the Exchange calldata (minus the 4 byte selector)
|
||||
/// @return value Corresponding 32 byte value stored at `offset` + 4.
|
||||
function loadExchangeData(uint256 offset)
|
||||
internal pure
|
||||
returns (bytes32 value);
|
||||
|
||||
/// @dev Extracts the maker address from an order stored in the Exchange calldata
|
||||
/// (which is embedded in `signedExchangeTransaction`).
|
||||
/// @param orderParamIndex Index of the order in the Exchange function's signature.
|
||||
/// @return makerAddress The extracted maker address.
|
||||
function loadMakerAddressFromOrder(uint256 orderParamIndex)
|
||||
internal pure
|
||||
returns (address makerAddress);
|
||||
|
||||
/// @dev Extracts the maker addresses from an array of orders stored in the Exchange calldata
|
||||
/// (which is embedded in `signedExchangeTransaction`).
|
||||
/// @param orderArrayParamIndex Index of the order array in the Exchange function's signature
|
||||
/// @return makerAddresses The extracted maker addresses.
|
||||
function loadMakerAddressesFromOrderArray(uint256 orderArrayParamIndex)
|
||||
internal pure
|
||||
returns (address[] makerAddresses);
|
||||
}
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol";
|
||||
import "@0x/contracts-utils/contracts/utils/Ownable/Ownable.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./libs/LibConstants.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./libs/LibConstants.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-libs/contracts/libs/LibMath.sol";
|
||||
import "./libs/LibConstants.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract IAssets {
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./IForwarderCore.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-libs/contracts/libs/LibOrder.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol";
|
||||
import "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol";
|
||||
|
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
// solhint-disable
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/// This contract is intended to serve as a reference, but is not actually used for efficiency reasons.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../interfaces/IAssets.sol";
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-libs/contracts/libs/LibOrder.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract MWeth {
|
||||
|
195
contracts/extensions/contracts/OrderMatcher/MixinAssets.sol
Normal file
195
contracts/extensions/contracts/OrderMatcher/MixinAssets.sol
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol";
|
||||
import "@0x/contracts-utils/contracts/utils/Ownable/Ownable.sol";
|
||||
import "@0x/contracts-tokens/contracts/tokens/ERC20Token/IERC20Token.sol";
|
||||
import "@0x/contracts-tokens/contracts/tokens/ERC721Token/IERC721Token.sol";
|
||||
import "./mixins/MAssets.sol";
|
||||
import "./libs/LibConstants.sol";
|
||||
|
||||
|
||||
contract MixinAssets is
|
||||
MAssets,
|
||||
Ownable,
|
||||
LibConstants
|
||||
{
|
||||
using LibBytes for bytes;
|
||||
|
||||
/// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to
|
||||
/// function optimally, and this function allows the ZRX to be withdrawn by owner. It may also be
|
||||
/// used to withdraw assets that were accidentally sent to this contract.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to withdraw.
|
||||
function withdrawAsset(
|
||||
bytes assetData,
|
||||
uint256 amount
|
||||
)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
transferAssetToSender(assetData, amount);
|
||||
}
|
||||
|
||||
/// @dev Approves or disapproves an AssetProxy to spend asset.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to approve for respective proxy.
|
||||
function approveAssetProxy(
|
||||
bytes assetData,
|
||||
uint256 amount
|
||||
)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
bytes4 proxyId = assetData.readBytes4(0);
|
||||
|
||||
if (proxyId == ERC20_DATA_ID) {
|
||||
approveERC20Token(assetData, amount);
|
||||
} else if (proxyId == ERC721_DATA_ID) {
|
||||
approveERC721Token(assetData, amount);
|
||||
} else {
|
||||
revert("UNSUPPORTED_ASSET_PROXY");
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Transfers given amount of asset to sender.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to transfer to sender.
|
||||
function transferAssetToSender(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
internal
|
||||
{
|
||||
bytes4 proxyId = assetData.readBytes4(0);
|
||||
|
||||
if (proxyId == ERC20_DATA_ID) {
|
||||
transferERC20Token(assetData, amount);
|
||||
} else if (proxyId == ERC721_DATA_ID) {
|
||||
transferERC721Token(assetData, amount);
|
||||
} else {
|
||||
revert("UNSUPPORTED_ASSET_PROXY");
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Decodes ERC20 assetData and transfers given amount to sender.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to transfer to sender.
|
||||
function transferERC20Token(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
internal
|
||||
{
|
||||
// 4 byte id + 12 0 bytes before ABI encoded token address.
|
||||
address token = assetData.readAddress(16);
|
||||
|
||||
// Transfer tokens.
|
||||
// We do a raw call so we can check the success separate
|
||||
// from the return data.
|
||||
bool success = token.call(abi.encodeWithSelector(
|
||||
ERC20_TRANSFER_SELECTOR,
|
||||
msg.sender,
|
||||
amount
|
||||
));
|
||||
require(
|
||||
success,
|
||||
"TRANSFER_FAILED"
|
||||
);
|
||||
|
||||
// Check return data.
|
||||
// If there is no return data, we assume the token incorrectly
|
||||
// does not return a bool. In this case we expect it to revert
|
||||
// on failure, which was handled above.
|
||||
// If the token does return data, we require that it is a single
|
||||
// value that evaluates to true.
|
||||
assembly {
|
||||
if returndatasize {
|
||||
success := 0
|
||||
if eq(returndatasize, 32) {
|
||||
// First 64 bytes of memory are reserved scratch space
|
||||
returndatacopy(0, 0, 32)
|
||||
success := mload(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
require(
|
||||
success,
|
||||
"TRANSFER_FAILED"
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Decodes ERC721 assetData and transfers given amount to sender.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to transfer to sender.
|
||||
function transferERC721Token(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
internal
|
||||
{
|
||||
require(
|
||||
amount == 1,
|
||||
"INVALID_AMOUNT"
|
||||
);
|
||||
// Decode asset data.
|
||||
// 4 byte id + 12 0 bytes before ABI encoded token address.
|
||||
address token = assetData.readAddress(16);
|
||||
// 4 byte id + 32 byte ABI encoded token address before token id.
|
||||
uint256 tokenId = assetData.readUint256(36);
|
||||
|
||||
// Perform transfer.
|
||||
IERC721Token(token).transferFrom(
|
||||
address(this),
|
||||
msg.sender,
|
||||
tokenId
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Sets approval for ERC20 AssetProxy.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to approve for respective proxy.
|
||||
function approveERC20Token(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
internal
|
||||
{
|
||||
address token = assetData.readAddress(16);
|
||||
require(
|
||||
IERC20Token(token).approve(ERC20_PROXY_ADDRESS, amount),
|
||||
"APPROVAL_FAILED"
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Sets approval for ERC721 AssetProxy.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to approve for respective proxy.
|
||||
function approveERC721Token(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
internal
|
||||
{
|
||||
address token = assetData.readAddress(16);
|
||||
bool approval = amount >= 1;
|
||||
IERC721Token(token).setApprovalForAll(ERC721_PROXY_ADDRESS, approval);
|
||||
}
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./libs/LibConstants.sol";
|
||||
import "@0x/contracts-libs/contracts/libs/LibOrder.sol";
|
||||
import "@0x/contracts-libs/contracts/libs/LibFillResults.sol";
|
||||
import "@0x/contracts-utils/contracts/utils/Ownable/Ownable.sol";
|
||||
|
||||
|
||||
contract MixinMatchOrders is
|
||||
Ownable,
|
||||
LibConstants
|
||||
{
|
||||
/// @dev Match two complementary orders that have a profitable spread.
|
||||
/// Each order is filled at their respective price point. However, the calculations are
|
||||
/// carried out as though the orders are both being filled at the right order's price point.
|
||||
/// The profit made by the left order is then used to fill the right order as much as possible.
|
||||
/// This results in a spread being taken in terms of both assets. The spread is held within this contract.
|
||||
/// @param leftOrder First order to match.
|
||||
/// @param rightOrder Second order to match.
|
||||
/// @param leftSignature Proof that order was created by the left maker.
|
||||
/// @param rightSignature Proof that order was created by the right maker.
|
||||
function matchOrders(
|
||||
LibOrder.Order memory leftOrder,
|
||||
LibOrder.Order memory rightOrder,
|
||||
bytes memory leftSignature,
|
||||
bytes memory rightSignature
|
||||
)
|
||||
public
|
||||
onlyOwner
|
||||
{
|
||||
// Match orders, maximally filling `leftOrder`
|
||||
LibFillResults.MatchedFillResults memory matchedFillResults = EXCHANGE.matchOrders(
|
||||
leftOrder,
|
||||
rightOrder,
|
||||
leftSignature,
|
||||
rightSignature
|
||||
);
|
||||
|
||||
uint256 leftMakerAssetSpreadAmount = matchedFillResults.leftMakerAssetSpreadAmount;
|
||||
uint256 rightOrderTakerAssetAmount = rightOrder.takerAssetAmount;
|
||||
|
||||
// Do not attempt to call `fillOrder` if no spread was taken or `rightOrder` has been completely filled
|
||||
if (leftMakerAssetSpreadAmount == 0 || matchedFillResults.right.takerAssetFilledAmount == rightOrderTakerAssetAmount) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The `assetData` fields of the `rightOrder` could have been null for the `matchOrders` call. We reassign them before calling `fillOrder`.
|
||||
rightOrder.makerAssetData = leftOrder.takerAssetData;
|
||||
rightOrder.takerAssetData = leftOrder.makerAssetData;
|
||||
|
||||
// Query `rightOrder` info to check if it has been completely filled
|
||||
// We need to make this check in case the `rightOrder` was partially filled before the `matchOrders` call
|
||||
LibOrder.OrderInfo memory orderInfo = EXCHANGE.getOrderInfo(rightOrder);
|
||||
|
||||
// Do not attempt to call `fillOrder` if order has been completely filled
|
||||
if (orderInfo.orderTakerAssetFilledAmount == rightOrderTakerAssetAmount) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We do not need to pass in a signature since it was already validated in the `matchOrders` call
|
||||
EXCHANGE.fillOrder(
|
||||
rightOrder,
|
||||
leftMakerAssetSpreadAmount,
|
||||
""
|
||||
);
|
||||
}
|
||||
}
|
38
contracts/extensions/contracts/OrderMatcher/OrderMatcher.sol
Normal file
38
contracts/extensions/contracts/OrderMatcher/OrderMatcher.sol
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/Ownable/Ownable.sol";
|
||||
import "./libs/LibConstants.sol";
|
||||
import "./MixinMatchOrders.sol";
|
||||
import "./MixinAssets.sol";
|
||||
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
contract OrderMatcher is
|
||||
MixinMatchOrders,
|
||||
MixinAssets
|
||||
{
|
||||
constructor (address _exchange)
|
||||
public
|
||||
LibConstants(_exchange)
|
||||
Ownable()
|
||||
{}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract IAssets {
|
||||
|
||||
/// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to
|
||||
/// function optimally, and this function allows the ZRX to be withdrawn by owner. It may also be
|
||||
/// used to withdraw assets that were accidentally sent to this contract.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to withdraw.
|
||||
function withdrawAsset(
|
||||
bytes assetData,
|
||||
uint256 amount
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Approves or disapproves an AssetProxy to spend asset.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to approve for respective proxy.
|
||||
function approveAssetProxy(
|
||||
bytes assetData,
|
||||
uint256 amount
|
||||
)
|
||||
external;
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-libs/contracts/libs/LibOrder.sol";
|
||||
|
||||
|
||||
contract IMatchOrders {
|
||||
|
||||
/// @dev Match two complementary orders that have a profitable spread.
|
||||
/// Each order is filled at their respective price point. However, the calculations are
|
||||
/// carried out as though the orders are both being filled at the right order's price point.
|
||||
/// The profit made by the left order is then used to fill the right order as much as possible.
|
||||
/// This results in a spread being taken in terms of both assets. The spread is held within this contract.
|
||||
/// @param leftOrder First order to match.
|
||||
/// @param rightOrder Second order to match.
|
||||
/// @param leftSignature Proof that order was created by the left maker.
|
||||
/// @param rightSignature Proof that order was created by the right maker.
|
||||
function matchOrders(
|
||||
LibOrder.Order memory leftOrder,
|
||||
LibOrder.Order memory rightOrder,
|
||||
bytes memory leftSignature,
|
||||
bytes memory rightSignature
|
||||
)
|
||||
public;
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contract-utils/contracts/utils/Ownable/IOwnable.sol";
|
||||
import "./IMatchOrders.sol";
|
||||
import "./IAssets.sol";
|
||||
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
contract IOrderMatcher is
|
||||
IOwnable,
|
||||
IMatchOrders,
|
||||
IAssets
|
||||
{}
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol";
|
||||
|
||||
|
||||
contract LibConstants {
|
||||
|
||||
// bytes4(keccak256("transfer(address,uint256)"))
|
||||
bytes4 constant internal ERC20_TRANSFER_SELECTOR = 0xa9059cbb;
|
||||
// bytes4(keccak256("ERC20Token(address)"))
|
||||
bytes4 constant internal ERC20_DATA_ID = 0xf47261b0;
|
||||
// bytes4(keccak256("ERC721Token(address,uint256)"))
|
||||
bytes4 constant internal ERC721_DATA_ID = 0x02571792;
|
||||
|
||||
// solhint-disable var-name-mixedcase
|
||||
IExchange internal EXCHANGE;
|
||||
address internal ERC20_PROXY_ADDRESS;
|
||||
address internal ERC721_PROXY_ADDRESS;
|
||||
// solhint-enable var-name-mixedcase
|
||||
|
||||
constructor (address _exchange)
|
||||
public
|
||||
{
|
||||
EXCHANGE = IExchange(_exchange);
|
||||
|
||||
ERC20_PROXY_ADDRESS = EXCHANGE.getAssetProxy(ERC20_DATA_ID);
|
||||
require(
|
||||
ERC20_PROXY_ADDRESS != address(0),
|
||||
"UNREGISTERED_ASSET_PROXY"
|
||||
);
|
||||
|
||||
ERC721_PROXY_ADDRESS = EXCHANGE.getAssetProxy(ERC721_DATA_ID);
|
||||
require(
|
||||
ERC721_PROXY_ADDRESS != address(0),
|
||||
"UNREGISTERED_ASSET_PROXY"
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../interfaces/IAssets.sol";
|
||||
|
||||
|
||||
contract MAssets is
|
||||
IAssets
|
||||
{
|
||||
/// @dev Transfers given amount of asset to sender.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to transfer to sender.
|
||||
function transferAssetToSender(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
internal;
|
||||
|
||||
/// @dev Decodes ERC20 assetData and transfers given amount to sender.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to transfer to sender.
|
||||
function transferERC20Token(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
internal;
|
||||
|
||||
/// @dev Decodes ERC721 assetData and transfers given amount to sender.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to transfer to sender.
|
||||
function transferERC721Token(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
internal;
|
||||
|
||||
/// @dev Sets approval for ERC20 AssetProxy.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to approve for respective proxy.
|
||||
function approveERC20Token(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
internal;
|
||||
|
||||
/// @dev Sets approval for ERC721 AssetProxy.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of asset to approve for respective proxy.
|
||||
function approveERC721Token(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
internal;
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@0x/contracts-extensions",
|
||||
"version": "1.0.1",
|
||||
"version": "1.2.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -20,7 +19,8 @@
|
||||
"test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html",
|
||||
"test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
||||
"compile": "sol-compiler --contracts-dir contracts",
|
||||
"compile": "sol-compiler",
|
||||
"watch": "sol-compiler -w",
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
@@ -32,7 +32,7 @@
|
||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
|
||||
},
|
||||
"config": {
|
||||
"abis": "generated-artifacts/@(DutchAuction|Forwarder).json"
|
||||
"abis": "generated-artifacts/@(BalanceThresholdFilter|DutchAuction|Forwarder|OrderMatcher|OrderValidator).json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -44,12 +44,13 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.19",
|
||||
"@0x/contracts-test-utils": "^1.0.2",
|
||||
"@0x/dev-utils": "^1.0.21",
|
||||
"@0x/sol-compiler": "^1.1.16",
|
||||
"@0x/sol-cov": "^2.1.16",
|
||||
"@0x/subproviders": "^2.1.8",
|
||||
"@0x/abi-gen": "^1.0.20",
|
||||
"@0x/contract-wrappers": "^4.2.0",
|
||||
"@0x/contracts-test-utils": "^1.0.3",
|
||||
"@0x/dev-utils": "^1.0.22",
|
||||
"@0x/sol-compiler": "^2.0.0",
|
||||
"@0x/sol-cov": "^2.1.17",
|
||||
"@0x/subproviders": "^2.1.9",
|
||||
"@0x/tslint-config": "^2.0.0",
|
||||
"@types/bn.js": "^4.11.0",
|
||||
"@types/lodash": "4.14.104",
|
||||
@@ -64,24 +65,23 @@
|
||||
"mocha": "^4.1.0",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"shx": "^0.2.2",
|
||||
"solc": "^0.4.24",
|
||||
"solhint": "^1.4.1",
|
||||
"tslint": "5.11.0",
|
||||
"typescript": "3.0.1",
|
||||
"yargs": "^10.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.10",
|
||||
"@0x/contracts-interfaces": "^1.0.1",
|
||||
"@0x/contracts-libs": "^1.0.1",
|
||||
"@0x/contracts-protocol": "^2.1.58",
|
||||
"@0x/contracts-tokens": "^1.0.1",
|
||||
"@0x/contracts-utils": "^1.0.1",
|
||||
"@0x/order-utils": "^3.0.7",
|
||||
"@0x/types": "^1.4.1",
|
||||
"@0x/base-contract": "^3.0.11",
|
||||
"@0x/contracts-interfaces": "^1.0.3",
|
||||
"@0x/contracts-libs": "^1.0.3",
|
||||
"@0x/contracts-protocol": "^2.2.0",
|
||||
"@0x/contracts-tokens": "^1.0.3",
|
||||
"@0x/contracts-utils": "^1.0.3",
|
||||
"@0x/order-utils": "^3.1.0",
|
||||
"@0x/types": "^1.5.0",
|
||||
"@0x/typescript-typings": "^3.0.6",
|
||||
"@0x/utils": "^2.0.8",
|
||||
"@0x/web3-wrapper": "^3.2.1",
|
||||
"@0x/utils": "^2.1.1",
|
||||
"@0x/web3-wrapper": "^3.2.2",
|
||||
"@types/js-combinatorics": "^0.5.29",
|
||||
"bn.js": "^4.11.8",
|
||||
"ethereum-types": "^1.1.4",
|
||||
|
@@ -1,9 +1,15 @@
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as BalanceThresholdFilter from '../../generated-artifacts/BalanceThresholdFilter.json';
|
||||
import * as DutchAuction from '../../generated-artifacts/DutchAuction.json';
|
||||
import * as Forwarder from '../../generated-artifacts/Forwarder.json';
|
||||
import * as OrderMatcher from '../../generated-artifacts/OrderMatcher.json';
|
||||
import * as OrderValidator from '../../generated-artifacts/OrderValidator.json';
|
||||
|
||||
export const artifacts = {
|
||||
BalanceThresholdFilter: BalanceThresholdFilter as ContractArtifact,
|
||||
DutchAuction: DutchAuction as ContractArtifact,
|
||||
Forwarder: Forwarder as ContractArtifact,
|
||||
OrderMatcher: OrderMatcher as ContractArtifact,
|
||||
OrderValidator: OrderValidator as ContractArtifact,
|
||||
};
|
||||
|
@@ -1,2 +1,5 @@
|
||||
export * from '../../generated-wrappers/balance_threshold_filter';
|
||||
export * from '../../generated-wrappers/dutch_auction';
|
||||
export * from '../../generated-wrappers/forwarder';
|
||||
export * from '../../generated-wrappers/order_matcher';
|
||||
export * from '../../generated-wrappers/order_validator';
|
||||
|
1644
contracts/extensions/test/extensions/balance_threshold_filter.ts
Normal file
1644
contracts/extensions/test/extensions/balance_threshold_filter.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
import { DutchAuctionWrapper } from '@0x/contract-wrappers';
|
||||
import {
|
||||
artifacts as protocolArtifacts,
|
||||
ERC20Wrapper,
|
||||
@@ -29,12 +30,11 @@ import { RevertReason, SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import ethAbi = require('ethereumjs-abi');
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { DutchAuctionContract } from '../../generated-wrappers/dutch_auction';
|
||||
import { artifacts } from '../../src/artifacts';
|
||||
import { DutchAuctionTestWrapper } from '../utils/dutch_auction_test_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
@@ -68,19 +68,8 @@ describe(ContractName.DutchAuction, () => {
|
||||
let erc721MakerAssetIds: BigNumber[];
|
||||
const tenMinutesInSeconds = 10 * 60;
|
||||
|
||||
function extendMakerAssetData(makerAssetData: string, beginTimeSeconds: BigNumber, beginAmount: BigNumber): string {
|
||||
return ethUtil.bufferToHex(
|
||||
Buffer.concat([
|
||||
ethUtil.toBuffer(makerAssetData),
|
||||
ethUtil.toBuffer(
|
||||
(ethAbi as any).rawEncode(
|
||||
['uint256', 'uint256'],
|
||||
[beginTimeSeconds.toString(), beginAmount.toString()],
|
||||
),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
let dutchAuctionTestWrapper: DutchAuctionTestWrapper;
|
||||
let defaultERC20MakerAssetData: string;
|
||||
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
@@ -136,6 +125,7 @@ describe(ContractName.DutchAuction, () => {
|
||||
dutchAuctionInstance.address,
|
||||
provider,
|
||||
);
|
||||
dutchAuctionTestWrapper = new DutchAuctionTestWrapper(dutchAuctionInstance, provider);
|
||||
|
||||
defaultMakerAssetAddress = erc20TokenA.address;
|
||||
const defaultTakerAssetAddress = wethContract.address;
|
||||
@@ -174,7 +164,7 @@ describe(ContractName.DutchAuction, () => {
|
||||
feeRecipientAddress,
|
||||
// taker address or sender address should be set to the ducth auction contract
|
||||
takerAddress: dutchAuctionContract.address,
|
||||
makerAssetData: extendMakerAssetData(
|
||||
makerAssetData: DutchAuctionWrapper.encodeDutchAuctionAssetData(
|
||||
assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
@@ -199,6 +189,7 @@ describe(ContractName.DutchAuction, () => {
|
||||
const takerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(takerAddress)];
|
||||
sellerOrderFactory = new OrderFactory(makerPrivateKey, sellerDefaultOrderParams);
|
||||
buyerOrderFactory = new OrderFactory(takerPrivateKey, buyerDefaultOrderParams);
|
||||
defaultERC20MakerAssetData = assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress);
|
||||
});
|
||||
after(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
@@ -215,49 +206,41 @@ describe(ContractName.DutchAuction, () => {
|
||||
describe('matchOrders', () => {
|
||||
it('should be worth the begin price at the begining of the auction', async () => {
|
||||
auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp + 2);
|
||||
sellOrder = await sellerOrderFactory.newSignedOrderAsync({
|
||||
makerAssetData: extendMakerAssetData(
|
||||
assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
),
|
||||
});
|
||||
const auctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
|
||||
const makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData(
|
||||
defaultERC20MakerAssetData,
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
);
|
||||
sellOrder = await sellerOrderFactory.newSignedOrderAsync({ makerAssetData });
|
||||
const auctionDetails = await dutchAuctionTestWrapper.getAuctionDetailsAsync(sellOrder);
|
||||
expect(auctionDetails.currentTimeSeconds).to.be.bignumber.lte(auctionBeginTimeSeconds);
|
||||
expect(auctionDetails.currentAmount).to.be.bignumber.equal(auctionBeginAmount);
|
||||
expect(auctionDetails.beginAmount).to.be.bignumber.equal(auctionBeginAmount);
|
||||
});
|
||||
it('should be be worth the end price at the end of the auction', async () => {
|
||||
auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds * 2);
|
||||
auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds);
|
||||
const makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData(
|
||||
defaultERC20MakerAssetData,
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
);
|
||||
sellOrder = await sellerOrderFactory.newSignedOrderAsync({
|
||||
makerAssetData: extendMakerAssetData(
|
||||
assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
),
|
||||
makerAssetData,
|
||||
expirationTimeSeconds: auctionEndTimeSeconds,
|
||||
});
|
||||
const auctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
|
||||
const auctionDetails = await dutchAuctionTestWrapper.getAuctionDetailsAsync(sellOrder);
|
||||
expect(auctionDetails.currentTimeSeconds).to.be.bignumber.gte(auctionEndTimeSeconds);
|
||||
expect(auctionDetails.currentAmount).to.be.bignumber.equal(auctionEndAmount);
|
||||
expect(auctionDetails.beginAmount).to.be.bignumber.equal(auctionBeginAmount);
|
||||
});
|
||||
it('should match orders at current amount and send excess to buyer', async () => {
|
||||
const beforeAuctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
|
||||
const beforeAuctionDetails = await dutchAuctionTestWrapper.getAuctionDetailsAsync(sellOrder);
|
||||
buyOrder = await buyerOrderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: beforeAuctionDetails.currentAmount.times(2),
|
||||
});
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await dutchAuctionContract.matchOrders.sendTransactionAsync(
|
||||
buyOrder,
|
||||
sellOrder,
|
||||
buyOrder.signature,
|
||||
sellOrder.signature,
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
),
|
||||
);
|
||||
const afterAuctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
|
||||
await dutchAuctionTestWrapper.matchOrdersAsync(buyOrder, sellOrder, takerAddress);
|
||||
const afterAuctionDetails = await dutchAuctionTestWrapper.getAuctionDetailsAsync(sellOrder);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
expect(newBalances[dutchAuctionContract.address][wethContract.address]).to.be.bignumber.equal(
|
||||
constants.ZERO_AMOUNT,
|
||||
@@ -276,17 +259,8 @@ describe(ContractName.DutchAuction, () => {
|
||||
sellOrder = await sellerOrderFactory.newSignedOrderAsync({
|
||||
makerFee: new BigNumber(1),
|
||||
});
|
||||
const txHash = await dutchAuctionContract.matchOrders.sendTransactionAsync(
|
||||
buyOrder,
|
||||
sellOrder,
|
||||
buyOrder.signature,
|
||||
sellOrder.signature,
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
const afterAuctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
|
||||
await dutchAuctionTestWrapper.matchOrdersAsync(buyOrder, sellOrder, takerAddress);
|
||||
const afterAuctionDetails = await dutchAuctionTestWrapper.getAuctionDetailsAsync(sellOrder);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
expect(newBalances[makerAddress][wethContract.address]).to.be.bignumber.gte(
|
||||
erc20Balances[makerAddress][wethContract.address].plus(afterAuctionDetails.currentAmount),
|
||||
@@ -299,18 +273,9 @@ describe(ContractName.DutchAuction, () => {
|
||||
buyOrder = await buyerOrderFactory.newSignedOrderAsync({
|
||||
makerFee: new BigNumber(1),
|
||||
});
|
||||
const txHash = await dutchAuctionContract.matchOrders.sendTransactionAsync(
|
||||
buyOrder,
|
||||
sellOrder,
|
||||
buyOrder.signature,
|
||||
sellOrder.signature,
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
await dutchAuctionTestWrapper.matchOrdersAsync(buyOrder, sellOrder, takerAddress);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
const afterAuctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
|
||||
const afterAuctionDetails = await dutchAuctionTestWrapper.getAuctionDetailsAsync(sellOrder);
|
||||
expect(newBalances[makerAddress][wethContract.address]).to.be.bignumber.gte(
|
||||
erc20Balances[makerAddress][wethContract.address].plus(afterAuctionDetails.currentAmount),
|
||||
);
|
||||
@@ -321,24 +286,17 @@ describe(ContractName.DutchAuction, () => {
|
||||
it('should revert when auction expires', async () => {
|
||||
auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds * 2);
|
||||
auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds);
|
||||
const makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData(
|
||||
defaultERC20MakerAssetData,
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
);
|
||||
sellOrder = await sellerOrderFactory.newSignedOrderAsync({
|
||||
expirationTimeSeconds: auctionEndTimeSeconds,
|
||||
makerAssetData: extendMakerAssetData(
|
||||
assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
),
|
||||
makerAssetData,
|
||||
});
|
||||
return expectTransactionFailedAsync(
|
||||
dutchAuctionContract.matchOrders.sendTransactionAsync(
|
||||
buyOrder,
|
||||
sellOrder,
|
||||
buyOrder.signature,
|
||||
sellOrder.signature,
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
),
|
||||
dutchAuctionTestWrapper.matchOrdersAsync(buyOrder, sellOrder, takerAddress),
|
||||
RevertReason.AuctionExpired,
|
||||
);
|
||||
});
|
||||
@@ -347,15 +305,7 @@ describe(ContractName.DutchAuction, () => {
|
||||
makerAssetAmount: sellOrder.takerAssetAmount,
|
||||
});
|
||||
return expectTransactionFailedAsync(
|
||||
dutchAuctionContract.matchOrders.sendTransactionAsync(
|
||||
buyOrder,
|
||||
sellOrder,
|
||||
buyOrder.signature,
|
||||
sellOrder.signature,
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
),
|
||||
dutchAuctionTestWrapper.matchOrdersAsync(buyOrder, sellOrder, takerAddress),
|
||||
RevertReason.AuctionInvalidAmount,
|
||||
);
|
||||
});
|
||||
@@ -364,38 +314,23 @@ describe(ContractName.DutchAuction, () => {
|
||||
takerAssetAmount: auctionBeginAmount.plus(1),
|
||||
});
|
||||
return expectTransactionFailedAsync(
|
||||
dutchAuctionContract.matchOrders.sendTransactionAsync(
|
||||
buyOrder,
|
||||
sellOrder,
|
||||
buyOrder.signature,
|
||||
sellOrder.signature,
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
),
|
||||
dutchAuctionTestWrapper.matchOrdersAsync(buyOrder, sellOrder, takerAddress),
|
||||
RevertReason.AuctionInvalidAmount,
|
||||
);
|
||||
});
|
||||
it('begin time is less than end time', async () => {
|
||||
auctionBeginTimeSeconds = new BigNumber(auctionEndTimeSeconds).plus(tenMinutesInSeconds);
|
||||
const makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData(
|
||||
defaultERC20MakerAssetData,
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
);
|
||||
sellOrder = await sellerOrderFactory.newSignedOrderAsync({
|
||||
expirationTimeSeconds: auctionEndTimeSeconds,
|
||||
makerAssetData: extendMakerAssetData(
|
||||
assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
),
|
||||
makerAssetData,
|
||||
});
|
||||
return expectTransactionFailedAsync(
|
||||
dutchAuctionContract.matchOrders.sendTransactionAsync(
|
||||
buyOrder,
|
||||
sellOrder,
|
||||
buyOrder.signature,
|
||||
sellOrder.signature,
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
),
|
||||
dutchAuctionTestWrapper.matchOrdersAsync(buyOrder, sellOrder, takerAddress),
|
||||
RevertReason.AuctionInvalidBeginTime,
|
||||
);
|
||||
});
|
||||
@@ -404,45 +339,30 @@ describe(ContractName.DutchAuction, () => {
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
});
|
||||
return expectTransactionFailedAsync(
|
||||
dutchAuctionContract.matchOrders.sendTransactionAsync(
|
||||
buyOrder,
|
||||
sellOrder,
|
||||
buyOrder.signature,
|
||||
sellOrder.signature,
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
),
|
||||
dutchAuctionTestWrapper.matchOrdersAsync(buyOrder, sellOrder, takerAddress),
|
||||
RevertReason.InvalidAssetData,
|
||||
);
|
||||
});
|
||||
|
||||
describe('ERC721', () => {
|
||||
it('should match orders when ERC721', async () => {
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
const erc721MakerAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId);
|
||||
const makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData(
|
||||
erc721MakerAssetData,
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
);
|
||||
sellOrder = await sellerOrderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
makerAssetData: extendMakerAssetData(
|
||||
assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
auctionBeginTimeSeconds,
|
||||
auctionBeginAmount,
|
||||
),
|
||||
makerAssetData,
|
||||
});
|
||||
buyOrder = await buyerOrderFactory.newSignedOrderAsync({
|
||||
takerAssetAmount: new BigNumber(1),
|
||||
takerAssetData: sellOrder.makerAssetData,
|
||||
});
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await dutchAuctionContract.matchOrders.sendTransactionAsync(
|
||||
buyOrder,
|
||||
sellOrder,
|
||||
buyOrder.signature,
|
||||
sellOrder.signature,
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
),
|
||||
);
|
||||
const afterAuctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
|
||||
await dutchAuctionTestWrapper.matchOrdersAsync(buyOrder, sellOrder, takerAddress);
|
||||
const afterAuctionDetails = await dutchAuctionTestWrapper.getAuctionDetailsAsync(sellOrder);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
// HACK gte used here due to a bug in ganache where the timestamp can change
|
||||
// between multiple calls to the same block. Which can move the amount in our case
|
||||
|
@@ -48,7 +48,6 @@ describe(ContractName.Forwarder, () => {
|
||||
let owner: string;
|
||||
let takerAddress: string;
|
||||
let feeRecipientAddress: string;
|
||||
let otherAddress: string;
|
||||
let defaultMakerAssetAddress: string;
|
||||
let zrxAssetData: string;
|
||||
let wethAssetData: string;
|
||||
@@ -78,7 +77,7 @@ describe(ContractName.Forwarder, () => {
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
||||
const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress, otherAddress] = accounts);
|
||||
const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress] = accounts);
|
||||
|
||||
const txHash = await web3Wrapper.sendTransactionAsync({ from: accounts[0], to: accounts[0], value: 0 });
|
||||
const transaction = await web3Wrapper.getTransactionByHashAsync(txHash);
|
||||
|
818
contracts/extensions/test/extensions/order_matcher.ts
Normal file
818
contracts/extensions/test/extensions/order_matcher.ts
Normal file
@@ -0,0 +1,818 @@
|
||||
import {
|
||||
artifacts as protocolArtifacts,
|
||||
ERC20ProxyContract,
|
||||
ERC20Wrapper,
|
||||
ERC721ProxyContract,
|
||||
ExchangeContract,
|
||||
ExchangeFillEventArgs,
|
||||
ExchangeWrapper,
|
||||
} from '@0x/contracts-protocol';
|
||||
import {
|
||||
chaiSetup,
|
||||
constants,
|
||||
ERC20BalancesByOwner,
|
||||
expectContractCreationFailedAsync,
|
||||
expectTransactionFailedAsync,
|
||||
LogDecoder,
|
||||
OrderFactory,
|
||||
provider,
|
||||
sendTransactionResult,
|
||||
txDefaults,
|
||||
web3Wrapper,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { artifacts as tokenArtifacts, DummyERC20TokenContract, DummyERC721TokenContract } from '@0x/contracts-tokens';
|
||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||
import { assetDataUtils } from '@0x/order-utils';
|
||||
import { RevertReason } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { OrderMatcherContract } from '../../generated-wrappers/order_matcher';
|
||||
import { artifacts } from '../../src/artifacts';
|
||||
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
describe('OrderMatcher', () => {
|
||||
let makerAddressLeft: string;
|
||||
let makerAddressRight: string;
|
||||
let owner: string;
|
||||
let takerAddress: string;
|
||||
let feeRecipientAddressLeft: string;
|
||||
let feeRecipientAddressRight: string;
|
||||
|
||||
let erc20TokenA: DummyERC20TokenContract;
|
||||
let erc20TokenB: DummyERC20TokenContract;
|
||||
let zrxToken: DummyERC20TokenContract;
|
||||
let exchange: ExchangeContract;
|
||||
let erc20Proxy: ERC20ProxyContract;
|
||||
let erc721Proxy: ERC721ProxyContract;
|
||||
let orderMatcher: OrderMatcherContract;
|
||||
|
||||
let erc20BalancesByOwner: ERC20BalancesByOwner;
|
||||
let exchangeWrapper: ExchangeWrapper;
|
||||
let erc20Wrapper: ERC20Wrapper;
|
||||
let orderFactoryLeft: OrderFactory;
|
||||
let orderFactoryRight: OrderFactory;
|
||||
|
||||
let leftMakerAssetData: string;
|
||||
let leftTakerAssetData: string;
|
||||
let defaultERC20MakerAssetAddress: string;
|
||||
let defaultERC20TakerAssetAddress: string;
|
||||
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
after(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
before(async () => {
|
||||
// Create accounts
|
||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
||||
// Hack(albrow): Both Prettier and TSLint insert a trailing comma below
|
||||
// but that is invalid syntax as of TypeScript version >= 2.8. We don't
|
||||
// have the right fine-grained configuration options in TSLint,
|
||||
// Prettier, or TypeScript, to reconcile this, so we will just have to
|
||||
// wait for them to sort it out. We disable TSLint and Prettier for
|
||||
// this part of the code for now. This occurs several times in this
|
||||
// file. See https://github.com/prettier/prettier/issues/4624.
|
||||
// prettier-ignore
|
||||
const usedAddresses = ([
|
||||
owner,
|
||||
makerAddressLeft,
|
||||
makerAddressRight,
|
||||
takerAddress,
|
||||
feeRecipientAddressLeft,
|
||||
// tslint:disable-next-line:trailing-comma
|
||||
feeRecipientAddressRight
|
||||
] = _.slice(accounts, 0, 6));
|
||||
// Create wrappers
|
||||
erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
|
||||
// Deploy ERC20 token & ERC20 proxy
|
||||
const numDummyErc20ToDeploy = 3;
|
||||
[erc20TokenA, erc20TokenB, zrxToken] = await erc20Wrapper.deployDummyTokensAsync(
|
||||
numDummyErc20ToDeploy,
|
||||
constants.DUMMY_TOKEN_DECIMALS,
|
||||
);
|
||||
erc20Proxy = await erc20Wrapper.deployProxyAsync();
|
||||
await erc20Wrapper.setBalancesAndAllowancesAsync();
|
||||
// Deploy ERC721 proxy
|
||||
erc721Proxy = await ERC721ProxyContract.deployFrom0xArtifactAsync(
|
||||
protocolArtifacts.ERC721Proxy,
|
||||
provider,
|
||||
txDefaults,
|
||||
);
|
||||
// Depoy exchange
|
||||
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
|
||||
protocolArtifacts.Exchange,
|
||||
provider,
|
||||
txDefaults,
|
||||
assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
);
|
||||
exchangeWrapper = new ExchangeWrapper(exchange, provider);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
|
||||
// Authorize ERC20 trades by exchange
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, {
|
||||
from: owner,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// Deploy OrderMatcher
|
||||
orderMatcher = await OrderMatcherContract.deployFrom0xArtifactAsync(
|
||||
artifacts.OrderMatcher,
|
||||
provider,
|
||||
txDefaults,
|
||||
exchange.address,
|
||||
);
|
||||
// Set default addresses
|
||||
defaultERC20MakerAssetAddress = erc20TokenA.address;
|
||||
defaultERC20TakerAssetAddress = erc20TokenB.address;
|
||||
leftMakerAssetData = assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress);
|
||||
leftTakerAssetData = assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress);
|
||||
// Set OrderMatcher balances and allowances
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20TokenA.setBalance.sendTransactionAsync(orderMatcher.address, constants.INITIAL_ERC20_BALANCE, {
|
||||
from: owner,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20TokenB.setBalance.sendTransactionAsync(orderMatcher.address, constants.INITIAL_ERC20_BALANCE, {
|
||||
from: owner,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await orderMatcher.approveAssetProxy.sendTransactionAsync(
|
||||
leftMakerAssetData,
|
||||
constants.INITIAL_ERC20_ALLOWANCE,
|
||||
),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await orderMatcher.approveAssetProxy.sendTransactionAsync(
|
||||
leftTakerAssetData,
|
||||
constants.INITIAL_ERC20_ALLOWANCE,
|
||||
),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// Create default order parameters
|
||||
const defaultOrderParamsLeft = {
|
||||
...constants.STATIC_ORDER_PARAMS,
|
||||
makerAddress: makerAddressLeft,
|
||||
exchangeAddress: exchange.address,
|
||||
makerAssetData: leftMakerAssetData,
|
||||
takerAssetData: leftTakerAssetData,
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
};
|
||||
const defaultOrderParamsRight = {
|
||||
...constants.STATIC_ORDER_PARAMS,
|
||||
makerAddress: makerAddressRight,
|
||||
exchangeAddress: exchange.address,
|
||||
makerAssetData: leftTakerAssetData,
|
||||
takerAssetData: leftMakerAssetData,
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
};
|
||||
const privateKeyLeft = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddressLeft)];
|
||||
orderFactoryLeft = new OrderFactory(privateKeyLeft, defaultOrderParamsLeft);
|
||||
const privateKeyRight = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddressRight)];
|
||||
orderFactoryRight = new OrderFactory(privateKeyRight, defaultOrderParamsRight);
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
describe('constructor', () => {
|
||||
it('should revert if assetProxy is unregistered', async () => {
|
||||
const exchangeInstance = await ExchangeContract.deployFrom0xArtifactAsync(
|
||||
protocolArtifacts.Exchange,
|
||||
provider,
|
||||
txDefaults,
|
||||
constants.NULL_BYTES,
|
||||
);
|
||||
return expectContractCreationFailedAsync(
|
||||
(OrderMatcherContract.deployFrom0xArtifactAsync(
|
||||
artifacts.OrderMatcher,
|
||||
provider,
|
||||
txDefaults,
|
||||
exchangeInstance.address,
|
||||
) as any) as sendTransactionResult,
|
||||
RevertReason.UnregisteredAssetProxy,
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('matchOrders', () => {
|
||||
beforeEach(async () => {
|
||||
erc20BalancesByOwner = await erc20Wrapper.getBalancesAsync();
|
||||
});
|
||||
it('should revert if not called by owner', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
});
|
||||
const data = exchange.matchOrders.getABIEncodedTransactionData(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
signedOrderLeft.signature,
|
||||
signedOrderRight.signature,
|
||||
);
|
||||
await expectTransactionFailedAsync(
|
||||
web3Wrapper.sendTransactionAsync({
|
||||
data,
|
||||
to: orderMatcher.address,
|
||||
from: takerAddress,
|
||||
gas: constants.MAX_MATCH_ORDERS_GAS,
|
||||
}),
|
||||
RevertReason.OnlyContractOwner,
|
||||
);
|
||||
});
|
||||
it('should transfer the correct amounts when orders completely fill each other', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
});
|
||||
// Match signedOrderLeft with signedOrderRight
|
||||
const expectedTransferAmounts = {
|
||||
// Left Maker
|
||||
amountSoldByLeftMaker: signedOrderLeft.makerAssetAmount,
|
||||
amountBoughtByLeftMaker: signedOrderLeft.takerAssetAmount,
|
||||
// Right Maker
|
||||
amountSoldByRightMaker: signedOrderRight.makerAssetAmount,
|
||||
amountBoughtByRightMaker: signedOrderRight.takerAssetAmount,
|
||||
// Taker
|
||||
leftMakerAssetSpreadAmount: signedOrderLeft.makerAssetAmount.minus(signedOrderRight.takerAssetAmount),
|
||||
};
|
||||
const initialLeftMakerAssetTakerBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
const data = exchange.matchOrders.getABIEncodedTransactionData(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
signedOrderLeft.signature,
|
||||
signedOrderRight.signature,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
data,
|
||||
to: orderMatcher.address,
|
||||
from: owner,
|
||||
gas: constants.MAX_MATCH_ORDERS_GAS,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const newLeftMakerAssetTakerBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
const newErc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
expect(newErc20Balances[makerAddressLeft][defaultERC20MakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressLeft][defaultERC20MakerAssetAddress].minus(
|
||||
expectedTransferAmounts.amountSoldByLeftMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressRight][defaultERC20TakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressRight][defaultERC20TakerAssetAddress].minus(
|
||||
expectedTransferAmounts.amountSoldByRightMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressLeft][defaultERC20TakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressLeft][defaultERC20TakerAssetAddress].plus(
|
||||
expectedTransferAmounts.amountBoughtByLeftMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressRight][defaultERC20MakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressRight][defaultERC20MakerAssetAddress].plus(
|
||||
expectedTransferAmounts.amountBoughtByRightMaker,
|
||||
),
|
||||
);
|
||||
expect(newLeftMakerAssetTakerBalance).to.be.bignumber.equal(
|
||||
initialLeftMakerAssetTakerBalance.plus(expectedTransferAmounts.leftMakerAssetSpreadAmount),
|
||||
);
|
||||
});
|
||||
it('should transfer the correct amounts when orders completely fill each other and taker doesnt take a profit', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
});
|
||||
// Match signedOrderLeft with signedOrderRight
|
||||
const expectedTransferAmounts = {
|
||||
// Left Maker
|
||||
amountSoldByLeftMaker: signedOrderLeft.makerAssetAmount,
|
||||
amountBoughtByLeftMaker: signedOrderLeft.takerAssetAmount,
|
||||
// Right Maker
|
||||
amountSoldByRightMaker: signedOrderRight.makerAssetAmount,
|
||||
amountBoughtByRightMaker: signedOrderRight.takerAssetAmount,
|
||||
};
|
||||
const initialLeftMakerAssetTakerBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
const data = exchange.matchOrders.getABIEncodedTransactionData(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
signedOrderLeft.signature,
|
||||
signedOrderRight.signature,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
data,
|
||||
to: orderMatcher.address,
|
||||
from: owner,
|
||||
gas: constants.MAX_MATCH_ORDERS_GAS,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const newLeftMakerAssetTakerBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
const newErc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
expect(newErc20Balances[makerAddressLeft][defaultERC20MakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressLeft][defaultERC20MakerAssetAddress].minus(
|
||||
expectedTransferAmounts.amountSoldByLeftMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressRight][defaultERC20TakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressRight][defaultERC20TakerAssetAddress].minus(
|
||||
expectedTransferAmounts.amountSoldByRightMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressLeft][defaultERC20TakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressLeft][defaultERC20TakerAssetAddress].plus(
|
||||
expectedTransferAmounts.amountBoughtByLeftMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressRight][defaultERC20MakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressRight][defaultERC20MakerAssetAddress].plus(
|
||||
expectedTransferAmounts.amountBoughtByRightMaker,
|
||||
),
|
||||
);
|
||||
expect(newLeftMakerAssetTakerBalance).to.be.bignumber.equal(initialLeftMakerAssetTakerBalance);
|
||||
});
|
||||
it('should transfer the correct amounts when left order is completely filled and right order would be partially filled', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(20), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(4), 18),
|
||||
});
|
||||
// Match signedOrderLeft with signedOrderRight
|
||||
const expectedTransferAmounts = {
|
||||
// Left Maker
|
||||
amountSoldByLeftMaker: signedOrderLeft.makerAssetAmount,
|
||||
amountBoughtByLeftMaker: signedOrderLeft.takerAssetAmount,
|
||||
// Right Maker
|
||||
amountSoldByRightMaker: signedOrderRight.makerAssetAmount,
|
||||
amountBoughtByRightMaker: signedOrderRight.takerAssetAmount,
|
||||
// Taker
|
||||
leftMakerAssetSpreadAmount: signedOrderLeft.makerAssetAmount.minus(signedOrderRight.takerAssetAmount),
|
||||
leftTakerAssetSpreadAmount: signedOrderRight.makerAssetAmount.minus(signedOrderLeft.takerAssetAmount),
|
||||
};
|
||||
const initialLeftMakerAssetTakerBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
const initialLeftTakerAssetTakerBalance = await erc20TokenB.balanceOf.callAsync(orderMatcher.address);
|
||||
// Match signedOrderLeft with signedOrderRight
|
||||
const data = exchange.matchOrders.getABIEncodedTransactionData(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
signedOrderLeft.signature,
|
||||
signedOrderRight.signature,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
data,
|
||||
to: orderMatcher.address,
|
||||
from: owner,
|
||||
gas: constants.MAX_MATCH_ORDERS_GAS,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const newLeftMakerAssetTakerBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
const newLeftTakerAssetTakerBalance = await erc20TokenB.balanceOf.callAsync(orderMatcher.address);
|
||||
const newErc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
expect(newErc20Balances[makerAddressLeft][defaultERC20MakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressLeft][defaultERC20MakerAssetAddress].minus(
|
||||
expectedTransferAmounts.amountSoldByLeftMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressRight][defaultERC20TakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressRight][defaultERC20TakerAssetAddress].minus(
|
||||
expectedTransferAmounts.amountSoldByRightMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressLeft][defaultERC20TakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressLeft][defaultERC20TakerAssetAddress].plus(
|
||||
expectedTransferAmounts.amountBoughtByLeftMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressRight][defaultERC20MakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressRight][defaultERC20MakerAssetAddress].plus(
|
||||
expectedTransferAmounts.amountBoughtByRightMaker,
|
||||
),
|
||||
);
|
||||
expect(newLeftMakerAssetTakerBalance).to.be.bignumber.equal(
|
||||
initialLeftMakerAssetTakerBalance.plus(expectedTransferAmounts.leftMakerAssetSpreadAmount),
|
||||
);
|
||||
expect(newLeftTakerAssetTakerBalance).to.be.bignumber.equal(
|
||||
initialLeftTakerAssetTakerBalance.plus(expectedTransferAmounts.leftTakerAssetSpreadAmount),
|
||||
);
|
||||
});
|
||||
it('should not call fillOrder when rightOrder is completely filled after matchOrders call and orders were never partially filled', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
});
|
||||
const data = exchange.matchOrders.getABIEncodedTransactionData(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
signedOrderLeft.signature,
|
||||
signedOrderRight.signature,
|
||||
);
|
||||
const logDecoder = new LogDecoder(web3Wrapper, { ...artifacts, ...tokenArtifacts, ...protocolArtifacts });
|
||||
const txReceipt = await logDecoder.getTxWithDecodedLogsAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
data,
|
||||
to: orderMatcher.address,
|
||||
from: owner,
|
||||
gas: constants.MAX_MATCH_ORDERS_GAS,
|
||||
}),
|
||||
);
|
||||
const fillLogs = _.filter(
|
||||
txReceipt.logs,
|
||||
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
|
||||
);
|
||||
// Only 2 Fill logs should exist for `matchOrders` call. `fillOrder` should not have been called and should not have emitted a Fill event.
|
||||
expect(fillLogs.length).to.be.equal(2);
|
||||
});
|
||||
it('should not call fillOrder when rightOrder is completely filled after matchOrders call and orders were initially partially filled', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
});
|
||||
await exchangeWrapper.fillOrderAsync(signedOrderLeft, takerAddress, {
|
||||
takerAssetFillAmount: signedOrderLeft.takerAssetAmount.dividedToIntegerBy(5),
|
||||
});
|
||||
await exchangeWrapper.fillOrderAsync(signedOrderRight, takerAddress, {
|
||||
takerAssetFillAmount: signedOrderRight.takerAssetAmount.dividedToIntegerBy(5),
|
||||
});
|
||||
const data = exchange.matchOrders.getABIEncodedTransactionData(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
signedOrderLeft.signature,
|
||||
signedOrderRight.signature,
|
||||
);
|
||||
const logDecoder = new LogDecoder(web3Wrapper, { ...artifacts, ...tokenArtifacts, ...protocolArtifacts });
|
||||
const txReceipt = await logDecoder.getTxWithDecodedLogsAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
data,
|
||||
to: orderMatcher.address,
|
||||
from: owner,
|
||||
gas: constants.MAX_MATCH_ORDERS_GAS,
|
||||
}),
|
||||
);
|
||||
const fillLogs = _.filter(
|
||||
txReceipt.logs,
|
||||
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
|
||||
);
|
||||
// Only 2 Fill logs should exist for `matchOrders` call. `fillOrder` should not have been called and should not have emitted a Fill event.
|
||||
expect(fillLogs.length).to.be.equal(2);
|
||||
});
|
||||
it('should only take a spread in rightMakerAsset if entire leftMakerAssetSpread amount can be used to fill rightOrder after matchOrders call', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.9), 18),
|
||||
});
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(990), 18),
|
||||
});
|
||||
const initialLeftMakerAssetSpreadAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(1.09), 18);
|
||||
const leftTakerAssetSpreadAmount = initialLeftMakerAssetSpreadAmount
|
||||
.times(signedOrderRight.makerAssetAmount)
|
||||
.dividedToIntegerBy(signedOrderRight.takerAssetAmount);
|
||||
// Match signedOrderLeft with signedOrderRight
|
||||
const expectedTransferAmounts = {
|
||||
// Left Maker
|
||||
amountSoldByLeftMaker: signedOrderLeft.makerAssetAmount,
|
||||
amountBoughtByLeftMaker: signedOrderLeft.takerAssetAmount,
|
||||
// Right Maker
|
||||
amountSoldByRightMaker: signedOrderLeft.takerAssetAmount.plus(leftTakerAssetSpreadAmount),
|
||||
amountBoughtByRightMaker: signedOrderLeft.makerAssetAmount,
|
||||
// Taker
|
||||
leftMakerAssetSpreadAmount: constants.ZERO_AMOUNT,
|
||||
leftTakerAssetSpreadAmount,
|
||||
};
|
||||
const initialLeftMakerAssetTakerBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
const initialLeftTakerAssetTakerBalance = await erc20TokenB.balanceOf.callAsync(orderMatcher.address);
|
||||
// Match signedOrderLeft with signedOrderRight
|
||||
const data = exchange.matchOrders.getABIEncodedTransactionData(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
signedOrderLeft.signature,
|
||||
signedOrderRight.signature,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
data,
|
||||
to: orderMatcher.address,
|
||||
from: owner,
|
||||
gas: constants.MAX_MATCH_ORDERS_GAS,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const newLeftMakerAssetTakerBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
const newLeftTakerAssetTakerBalance = await erc20TokenB.balanceOf.callAsync(orderMatcher.address);
|
||||
const newErc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
expect(newErc20Balances[makerAddressLeft][defaultERC20MakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressLeft][defaultERC20MakerAssetAddress].minus(
|
||||
expectedTransferAmounts.amountSoldByLeftMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressRight][defaultERC20TakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressRight][defaultERC20TakerAssetAddress].minus(
|
||||
expectedTransferAmounts.amountSoldByRightMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressLeft][defaultERC20TakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressLeft][defaultERC20TakerAssetAddress].plus(
|
||||
expectedTransferAmounts.amountBoughtByLeftMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressRight][defaultERC20MakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressRight][defaultERC20MakerAssetAddress].plus(
|
||||
expectedTransferAmounts.amountBoughtByRightMaker,
|
||||
),
|
||||
);
|
||||
expect(newLeftMakerAssetTakerBalance).to.be.bignumber.equal(
|
||||
initialLeftMakerAssetTakerBalance.plus(expectedTransferAmounts.leftMakerAssetSpreadAmount),
|
||||
);
|
||||
expect(newLeftTakerAssetTakerBalance).to.be.bignumber.equal(
|
||||
initialLeftTakerAssetTakerBalance.plus(expectedTransferAmounts.leftTakerAssetSpreadAmount),
|
||||
);
|
||||
});
|
||||
it("should succeed if rightOrder's makerAssetData and takerAssetData are not provided", async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(20), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(4), 18),
|
||||
});
|
||||
// Match signedOrderLeft with signedOrderRight
|
||||
const expectedTransferAmounts = {
|
||||
// Left Maker
|
||||
amountSoldByLeftMaker: signedOrderLeft.makerAssetAmount,
|
||||
amountBoughtByLeftMaker: signedOrderLeft.takerAssetAmount,
|
||||
// Right Maker
|
||||
amountSoldByRightMaker: signedOrderRight.makerAssetAmount,
|
||||
amountBoughtByRightMaker: signedOrderRight.takerAssetAmount,
|
||||
// Taker
|
||||
leftMakerAssetSpreadAmount: signedOrderLeft.makerAssetAmount.minus(signedOrderRight.takerAssetAmount),
|
||||
leftTakerAssetSpreadAmount: signedOrderRight.makerAssetAmount.minus(signedOrderLeft.takerAssetAmount),
|
||||
};
|
||||
const initialLeftMakerAssetTakerBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
const initialLeftTakerAssetTakerBalance = await erc20TokenB.balanceOf.callAsync(orderMatcher.address);
|
||||
// Match signedOrderLeft with signedOrderRight
|
||||
signedOrderRight.makerAssetData = constants.NULL_BYTES;
|
||||
signedOrderRight.takerAssetData = constants.NULL_BYTES;
|
||||
const data = exchange.matchOrders.getABIEncodedTransactionData(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
signedOrderLeft.signature,
|
||||
signedOrderRight.signature,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
data,
|
||||
to: orderMatcher.address,
|
||||
from: owner,
|
||||
gas: constants.MAX_MATCH_ORDERS_GAS,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const newLeftMakerAssetTakerBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
const newLeftTakerAssetTakerBalance = await erc20TokenB.balanceOf.callAsync(orderMatcher.address);
|
||||
const newErc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
expect(newErc20Balances[makerAddressLeft][defaultERC20MakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressLeft][defaultERC20MakerAssetAddress].minus(
|
||||
expectedTransferAmounts.amountSoldByLeftMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressRight][defaultERC20TakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressRight][defaultERC20TakerAssetAddress].minus(
|
||||
expectedTransferAmounts.amountSoldByRightMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressLeft][defaultERC20TakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressLeft][defaultERC20TakerAssetAddress].plus(
|
||||
expectedTransferAmounts.amountBoughtByLeftMaker,
|
||||
),
|
||||
);
|
||||
expect(newErc20Balances[makerAddressRight][defaultERC20MakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20BalancesByOwner[makerAddressRight][defaultERC20MakerAssetAddress].plus(
|
||||
expectedTransferAmounts.amountBoughtByRightMaker,
|
||||
),
|
||||
);
|
||||
expect(newLeftMakerAssetTakerBalance).to.be.bignumber.equal(
|
||||
initialLeftMakerAssetTakerBalance.plus(expectedTransferAmounts.leftMakerAssetSpreadAmount),
|
||||
);
|
||||
expect(newLeftTakerAssetTakerBalance).to.be.bignumber.equal(
|
||||
initialLeftTakerAssetTakerBalance.plus(expectedTransferAmounts.leftTakerAssetSpreadAmount),
|
||||
);
|
||||
});
|
||||
it('should revert with the correct reason if matchOrders call reverts', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
});
|
||||
signedOrderRight.signature = `0xff${signedOrderRight.signature.slice(4)}`;
|
||||
const data = exchange.matchOrders.getABIEncodedTransactionData(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
signedOrderLeft.signature,
|
||||
signedOrderRight.signature,
|
||||
);
|
||||
await expectTransactionFailedAsync(
|
||||
web3Wrapper.sendTransactionAsync({
|
||||
data,
|
||||
to: orderMatcher.address,
|
||||
from: owner,
|
||||
gas: constants.MAX_MATCH_ORDERS_GAS,
|
||||
}),
|
||||
RevertReason.InvalidOrderSignature,
|
||||
);
|
||||
});
|
||||
it('should revert with the correct reason if fillOrder call reverts', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(20), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(4), 18),
|
||||
});
|
||||
// Matcher will not have enough allowance to fill rightOrder
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await orderMatcher.approveAssetProxy.sendTransactionAsync(leftMakerAssetData, constants.ZERO_AMOUNT, {
|
||||
from: owner,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const data = exchange.matchOrders.getABIEncodedTransactionData(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
signedOrderLeft.signature,
|
||||
signedOrderRight.signature,
|
||||
);
|
||||
await expectTransactionFailedAsync(
|
||||
web3Wrapper.sendTransactionAsync({
|
||||
data,
|
||||
to: orderMatcher.address,
|
||||
from: owner,
|
||||
gas: constants.MAX_MATCH_ORDERS_GAS,
|
||||
}),
|
||||
RevertReason.TransferFailed,
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('withdrawAsset', () => {
|
||||
it('should allow owner to withdraw ERC20 tokens', async () => {
|
||||
const erc20AWithdrawAmount = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
expect(erc20AWithdrawAmount).to.be.bignumber.gt(constants.ZERO_AMOUNT);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await orderMatcher.withdrawAsset.sendTransactionAsync(leftMakerAssetData, erc20AWithdrawAmount, {
|
||||
from: owner,
|
||||
}),
|
||||
);
|
||||
const newBalance = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
expect(newBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
});
|
||||
it('should allow owner to withdraw ERC721 tokens', async () => {
|
||||
const erc721Token = await DummyERC721TokenContract.deployFrom0xArtifactAsync(
|
||||
tokenArtifacts.DummyERC721Token,
|
||||
provider,
|
||||
txDefaults,
|
||||
constants.DUMMY_TOKEN_NAME,
|
||||
constants.DUMMY_TOKEN_SYMBOL,
|
||||
);
|
||||
const tokenId = new BigNumber(1);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721Token.mint.sendTransactionAsync(orderMatcher.address, tokenId, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, tokenId);
|
||||
const withdrawAmount = new BigNumber(1);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await orderMatcher.withdrawAsset.sendTransactionAsync(assetData, withdrawAmount, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const erc721Owner = await erc721Token.ownerOf.callAsync(tokenId);
|
||||
expect(erc721Owner).to.be.equal(owner);
|
||||
});
|
||||
it('should revert if not called by owner', async () => {
|
||||
const erc20AWithdrawAmount = await erc20TokenA.balanceOf.callAsync(orderMatcher.address);
|
||||
expect(erc20AWithdrawAmount).to.be.bignumber.gt(constants.ZERO_AMOUNT);
|
||||
await expectTransactionFailedAsync(
|
||||
orderMatcher.withdrawAsset.sendTransactionAsync(leftMakerAssetData, erc20AWithdrawAmount, {
|
||||
from: takerAddress,
|
||||
}),
|
||||
RevertReason.OnlyContractOwner,
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('approveAssetProxy', () => {
|
||||
it('should be able to set an allowance for ERC20 tokens', async () => {
|
||||
const allowance = new BigNumber(55465465426546);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await orderMatcher.approveAssetProxy.sendTransactionAsync(leftMakerAssetData, allowance, {
|
||||
from: owner,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const newAllowance = await erc20TokenA.allowance.callAsync(orderMatcher.address, erc20Proxy.address);
|
||||
expect(newAllowance).to.be.bignumber.equal(allowance);
|
||||
});
|
||||
it('should be able to approve an ERC721 token by passing in allowance = 1', async () => {
|
||||
const erc721Token = await DummyERC721TokenContract.deployFrom0xArtifactAsync(
|
||||
tokenArtifacts.DummyERC721Token,
|
||||
provider,
|
||||
txDefaults,
|
||||
constants.DUMMY_TOKEN_NAME,
|
||||
constants.DUMMY_TOKEN_SYMBOL,
|
||||
);
|
||||
const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, constants.ZERO_AMOUNT);
|
||||
const allowance = new BigNumber(1);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await orderMatcher.approveAssetProxy.sendTransactionAsync(assetData, allowance, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const isApproved = await erc721Token.isApprovedForAll.callAsync(orderMatcher.address, erc721Proxy.address);
|
||||
expect(isApproved).to.be.equal(true);
|
||||
});
|
||||
it('should be able to approve an ERC721 token by passing in allowance > 1', async () => {
|
||||
const erc721Token = await DummyERC721TokenContract.deployFrom0xArtifactAsync(
|
||||
tokenArtifacts.DummyERC721Token,
|
||||
provider,
|
||||
txDefaults,
|
||||
constants.DUMMY_TOKEN_NAME,
|
||||
constants.DUMMY_TOKEN_SYMBOL,
|
||||
);
|
||||
const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, constants.ZERO_AMOUNT);
|
||||
const allowance = new BigNumber(2);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await orderMatcher.approveAssetProxy.sendTransactionAsync(assetData, allowance, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const isApproved = await erc721Token.isApprovedForAll.callAsync(orderMatcher.address, erc721Proxy.address);
|
||||
expect(isApproved).to.be.equal(true);
|
||||
});
|
||||
it('should revert if not called by owner', async () => {
|
||||
const approval = new BigNumber(1);
|
||||
await expectTransactionFailedAsync(
|
||||
orderMatcher.approveAssetProxy.sendTransactionAsync(leftMakerAssetData, approval, {
|
||||
from: takerAddress,
|
||||
}),
|
||||
RevertReason.OnlyContractOwner,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
// tslint:disable:max-file-line-count
|
||||
// tslint:enable:no-unnecessary-type-assertion
|
@@ -1,3 +1,12 @@
|
||||
import {
|
||||
artifacts as protocolArtifacts,
|
||||
ERC20ProxyContract,
|
||||
ERC20Wrapper,
|
||||
ERC721ProxyContract,
|
||||
ERC721Wrapper,
|
||||
ExchangeContract,
|
||||
ExchangeWrapper,
|
||||
} from '@0x/contracts-protocol';
|
||||
import {
|
||||
chaiSetup,
|
||||
constants,
|
||||
@@ -15,16 +24,8 @@ import { BigNumber } from '@0x/utils';
|
||||
import * as chai from 'chai';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import {
|
||||
artifacts,
|
||||
ERC20ProxyContract,
|
||||
ERC20Wrapper,
|
||||
ERC721ProxyContract,
|
||||
ERC721Wrapper,
|
||||
ExchangeContract,
|
||||
ExchangeWrapper,
|
||||
OrderValidatorContract,
|
||||
} from '../../src';
|
||||
import { OrderValidatorContract } from '../../generated-wrappers/order_validator';
|
||||
import { artifacts } from '../../src/artifacts/index';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
@@ -80,7 +81,7 @@ describe('OrderValidator', () => {
|
||||
|
||||
const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
|
||||
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
|
||||
artifacts.Exchange,
|
||||
protocolArtifacts.Exchange,
|
||||
provider,
|
||||
txDefaults,
|
||||
zrxAssetData,
|
283
contracts/extensions/test/utils/balance_threshold_wrapper.ts
Normal file
283
contracts/extensions/test/utils/balance_threshold_wrapper.ts
Normal file
@@ -0,0 +1,283 @@
|
||||
import { artifacts as protocolArtifacts, ExchangeContract } from '@0x/contracts-protocol';
|
||||
import {
|
||||
FillResults,
|
||||
formatters,
|
||||
LogDecoder,
|
||||
OrderInfo,
|
||||
orderUtils,
|
||||
TransactionFactory,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { artifacts as tokensArtifacts } from '@0x/contracts-tokens';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { BalanceThresholdFilterContract } from '../../generated-wrappers/balance_threshold_filter';
|
||||
import { artifacts } from '../../src/artifacts';
|
||||
|
||||
export class BalanceThresholdWrapper {
|
||||
private readonly _balanceThresholdFilter: BalanceThresholdFilterContract;
|
||||
private readonly _signerTransactionFactory: TransactionFactory;
|
||||
private readonly _exchange: ExchangeContract;
|
||||
private readonly _web3Wrapper: Web3Wrapper;
|
||||
private readonly _logDecoder: LogDecoder;
|
||||
constructor(
|
||||
balanceThresholdFilter: BalanceThresholdFilterContract,
|
||||
exchangeContract: ExchangeContract,
|
||||
signerTransactionFactory: TransactionFactory,
|
||||
provider: Provider,
|
||||
) {
|
||||
this._balanceThresholdFilter = balanceThresholdFilter;
|
||||
this._exchange = exchangeContract;
|
||||
this._signerTransactionFactory = signerTransactionFactory;
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
this._logDecoder = new LogDecoder(this._web3Wrapper, {
|
||||
...artifacts,
|
||||
...tokensArtifacts,
|
||||
...protocolArtifacts,
|
||||
});
|
||||
}
|
||||
public async fillOrderAsync(
|
||||
signedOrder: SignedOrder,
|
||||
from: string,
|
||||
opts: { takerAssetFillAmount?: BigNumber } = {},
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
|
||||
const data = this._exchange.fillOrder.getABIEncodedTransactionData(
|
||||
params.order,
|
||||
params.takerAssetFillAmount,
|
||||
params.signature,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from);
|
||||
return txReceipt;
|
||||
}
|
||||
public async fillOrKillOrderAsync(
|
||||
signedOrder: SignedOrder,
|
||||
from: string,
|
||||
opts: { takerAssetFillAmount?: BigNumber } = {},
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
|
||||
const data = this._exchange.fillOrKillOrder.getABIEncodedTransactionData(
|
||||
params.order,
|
||||
params.takerAssetFillAmount,
|
||||
params.signature,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from);
|
||||
return txReceipt;
|
||||
}
|
||||
public async fillOrderNoThrowAsync(
|
||||
signedOrder: SignedOrder,
|
||||
from: string,
|
||||
opts: { takerAssetFillAmount?: BigNumber; gas?: number } = {},
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
|
||||
const data = this._exchange.fillOrderNoThrow.getABIEncodedTransactionData(
|
||||
params.order,
|
||||
params.takerAssetFillAmount,
|
||||
params.signature,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from, opts.gas);
|
||||
return txReceipt;
|
||||
}
|
||||
public async batchFillOrdersAsync(
|
||||
orders: SignedOrder[],
|
||||
from: string,
|
||||
opts: { takerAssetFillAmounts?: BigNumber[] } = {},
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts);
|
||||
const data = this._exchange.batchFillOrders.getABIEncodedTransactionData(
|
||||
params.orders,
|
||||
params.takerAssetFillAmounts,
|
||||
params.signatures,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from);
|
||||
return txReceipt;
|
||||
}
|
||||
public async batchFillOrKillOrdersAsync(
|
||||
orders: SignedOrder[],
|
||||
from: string,
|
||||
opts: { takerAssetFillAmounts?: BigNumber[] } = {},
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts);
|
||||
const data = this._exchange.batchFillOrKillOrders.getABIEncodedTransactionData(
|
||||
params.orders,
|
||||
params.takerAssetFillAmounts,
|
||||
params.signatures,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from);
|
||||
return txReceipt;
|
||||
}
|
||||
public async batchFillOrdersNoThrowAsync(
|
||||
orders: SignedOrder[],
|
||||
from: string,
|
||||
opts: { takerAssetFillAmounts?: BigNumber[]; gas?: number } = {},
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts);
|
||||
const data = this._exchange.batchFillOrKillOrders.getABIEncodedTransactionData(
|
||||
params.orders,
|
||||
params.takerAssetFillAmounts,
|
||||
params.signatures,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from, opts.gas);
|
||||
return txReceipt;
|
||||
}
|
||||
public async marketSellOrdersAsync(
|
||||
orders: SignedOrder[],
|
||||
from: string,
|
||||
opts: { takerAssetFillAmount: BigNumber },
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = formatters.createMarketSellOrders(orders, opts.takerAssetFillAmount);
|
||||
const data = this._exchange.marketSellOrders.getABIEncodedTransactionData(
|
||||
params.orders,
|
||||
params.takerAssetFillAmount,
|
||||
params.signatures,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from);
|
||||
return txReceipt;
|
||||
}
|
||||
public async marketSellOrdersNoThrowAsync(
|
||||
orders: SignedOrder[],
|
||||
from: string,
|
||||
opts: { takerAssetFillAmount: BigNumber; gas?: number },
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = formatters.createMarketSellOrders(orders, opts.takerAssetFillAmount);
|
||||
const data = this._exchange.marketSellOrdersNoThrow.getABIEncodedTransactionData(
|
||||
params.orders,
|
||||
params.takerAssetFillAmount,
|
||||
params.signatures,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from, opts.gas);
|
||||
return txReceipt;
|
||||
}
|
||||
public async marketBuyOrdersAsync(
|
||||
orders: SignedOrder[],
|
||||
from: string,
|
||||
opts: { makerAssetFillAmount: BigNumber },
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = formatters.createMarketBuyOrders(orders, opts.makerAssetFillAmount);
|
||||
const data = this._exchange.marketBuyOrders.getABIEncodedTransactionData(
|
||||
params.orders,
|
||||
params.makerAssetFillAmount,
|
||||
params.signatures,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from);
|
||||
return txReceipt;
|
||||
}
|
||||
public async marketBuyOrdersNoThrowAsync(
|
||||
orders: SignedOrder[],
|
||||
from: string,
|
||||
opts: { makerAssetFillAmount: BigNumber; gas?: number },
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = formatters.createMarketBuyOrders(orders, opts.makerAssetFillAmount);
|
||||
const data = this._exchange.marketBuyOrdersNoThrow.getABIEncodedTransactionData(
|
||||
params.orders,
|
||||
params.makerAssetFillAmount,
|
||||
params.signatures,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from, opts.gas);
|
||||
return txReceipt;
|
||||
}
|
||||
public async cancelOrderAsync(signedOrder: SignedOrder, from: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = orderUtils.createCancel(signedOrder);
|
||||
const data = this._exchange.cancelOrder.getABIEncodedTransactionData(params.order);
|
||||
const txReceipt = this._executeTransactionAsync(data, from);
|
||||
return txReceipt;
|
||||
}
|
||||
public async batchCancelOrdersAsync(
|
||||
orders: SignedOrder[],
|
||||
from: string,
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = formatters.createBatchCancel(orders);
|
||||
const data = this._exchange.batchCancelOrders.getABIEncodedTransactionData(params.orders);
|
||||
const txReceipt = this._executeTransactionAsync(data, from);
|
||||
return txReceipt;
|
||||
}
|
||||
public async cancelOrdersUpToAsync(salt: BigNumber, from: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const data = this._exchange.cancelOrdersUpTo.getABIEncodedTransactionData(salt);
|
||||
const txReceipt = this._executeTransactionAsync(data, from);
|
||||
return txReceipt;
|
||||
}
|
||||
public async getTakerAssetFilledAmountAsync(orderHashHex: string): Promise<BigNumber> {
|
||||
const filledAmount = await this._exchange.filled.callAsync(orderHashHex);
|
||||
return filledAmount;
|
||||
}
|
||||
public async isCancelledAsync(orderHashHex: string): Promise<boolean> {
|
||||
const isCancelled = await this._exchange.cancelled.callAsync(orderHashHex);
|
||||
return isCancelled;
|
||||
}
|
||||
public async getOrderEpochAsync(makerAddress: string, senderAddress: string): Promise<BigNumber> {
|
||||
const orderEpoch = await this._exchange.orderEpoch.callAsync(makerAddress, senderAddress);
|
||||
return orderEpoch;
|
||||
}
|
||||
public async getOrderInfoAsync(signedOrder: SignedOrder): Promise<OrderInfo> {
|
||||
const orderInfo = await this._exchange.getOrderInfo.callAsync(signedOrder);
|
||||
return orderInfo;
|
||||
}
|
||||
public async getOrdersInfoAsync(signedOrders: SignedOrder[]): Promise<OrderInfo[]> {
|
||||
const ordersInfo = (await this._exchange.getOrdersInfo.callAsync(signedOrders)) as OrderInfo[];
|
||||
return ordersInfo;
|
||||
}
|
||||
public async matchOrdersAsync(
|
||||
signedOrderLeft: SignedOrder,
|
||||
signedOrderRight: SignedOrder,
|
||||
from: string,
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
|
||||
const data = await this._exchange.matchOrders.getABIEncodedTransactionData(
|
||||
params.left,
|
||||
params.right,
|
||||
params.leftSignature,
|
||||
params.rightSignature,
|
||||
);
|
||||
const txReceipt = this._executeTransactionAsync(data, from);
|
||||
return txReceipt;
|
||||
}
|
||||
public async getFillOrderResultsAsync(
|
||||
signedOrder: SignedOrder,
|
||||
from: string,
|
||||
opts: { takerAssetFillAmount?: BigNumber } = {},
|
||||
): Promise<FillResults> {
|
||||
const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
|
||||
const fillResults = await this._exchange.fillOrder.callAsync(
|
||||
params.order,
|
||||
params.takerAssetFillAmount,
|
||||
params.signature,
|
||||
{ from },
|
||||
);
|
||||
return fillResults;
|
||||
}
|
||||
public abiEncodeFillOrder(signedOrder: SignedOrder, opts: { takerAssetFillAmount?: BigNumber } = {}): string {
|
||||
const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
|
||||
const data = this._exchange.fillOrder.getABIEncodedTransactionData(
|
||||
params.order,
|
||||
params.takerAssetFillAmount,
|
||||
params.signature,
|
||||
);
|
||||
return data;
|
||||
}
|
||||
public getBalanceThresholdAddress(): string {
|
||||
return this._balanceThresholdFilter.address;
|
||||
}
|
||||
public getExchangeAddress(): string {
|
||||
return this._exchange.address;
|
||||
}
|
||||
private async _executeTransactionAsync(
|
||||
abiEncodedExchangeTxData: string,
|
||||
from: string,
|
||||
gas?: number,
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const signedExchangeTx = this._signerTransactionFactory.newSignedTransaction(abiEncodedExchangeTxData);
|
||||
const txOpts = _.isUndefined(gas) ? { from } : { from, gas };
|
||||
const txHash = await this._balanceThresholdFilter.executeTransaction.sendTransactionAsync(
|
||||
signedExchangeTx.salt,
|
||||
signedExchangeTx.signerAddress,
|
||||
signedExchangeTx.data,
|
||||
signedExchangeTx.signature,
|
||||
txOpts,
|
||||
);
|
||||
const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return txReceipt;
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
import { artifacts as protocolArtifacts } from '@0x/contracts-protocol';
|
||||
import { LogDecoder } from '@0x/contracts-test-utils';
|
||||
import { artifacts as tokensArtifacts } from '@0x/contracts-tokens';
|
||||
import { DutchAuctionDetails, SignedOrder } from '@0x/types';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { DutchAuctionContract } from '../../generated-wrappers/dutch_auction';
|
||||
import { artifacts } from '../../src/artifacts';
|
||||
|
||||
export class DutchAuctionTestWrapper {
|
||||
private readonly _dutchAuctionContract: DutchAuctionContract;
|
||||
private readonly _web3Wrapper: Web3Wrapper;
|
||||
private readonly _logDecoder: LogDecoder;
|
||||
|
||||
constructor(contractInstance: DutchAuctionContract, provider: Provider) {
|
||||
this._dutchAuctionContract = contractInstance;
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
this._logDecoder = new LogDecoder(this._web3Wrapper, {
|
||||
...artifacts,
|
||||
...tokensArtifacts,
|
||||
...protocolArtifacts,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Matches the buy and sell orders at an amount given the following: the current block time, the auction
|
||||
* start time and the auction begin amount. The sell order is a an order at the lowest amount
|
||||
* at the end of the auction. Excess from the match is transferred to the seller.
|
||||
* Over time the price moves from beginAmount to endAmount given the current block.timestamp.
|
||||
* @param buyOrder The Buyer's order. This order is for the current expected price of the auction.
|
||||
* @param sellOrder The Seller's order. This order is for the lowest amount (at the end of the auction).
|
||||
* @param from Address the transaction is being sent from.
|
||||
* @return Transaction receipt with decoded logs.
|
||||
*/
|
||||
public async matchOrdersAsync(
|
||||
buyOrder: SignedOrder,
|
||||
sellOrder: SignedOrder,
|
||||
from: string,
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const txHash = await this._dutchAuctionContract.matchOrders.sendTransactionAsync(
|
||||
buyOrder,
|
||||
sellOrder,
|
||||
buyOrder.signature,
|
||||
sellOrder.signature,
|
||||
{
|
||||
from,
|
||||
},
|
||||
);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
/**
|
||||
* Calculates the Auction Details for the given order
|
||||
* @param sellOrder The Seller's order. This order is for the lowest amount (at the end of the auction).
|
||||
* @return The dutch auction details.
|
||||
*/
|
||||
public async getAuctionDetailsAsync(sellOrder: SignedOrder): Promise<DutchAuctionDetails> {
|
||||
const auctionDetails = await this._dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
|
||||
return auctionDetails;
|
||||
}
|
||||
}
|
@@ -6,6 +6,12 @@
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||
"files": ["./generated-artifacts/DutchAuction.json", "./generated-artifacts/Forwarder.json"],
|
||||
"files": [
|
||||
"./generated-artifacts/BalanceThresholdFilter.json",
|
||||
"./generated-artifacts/DutchAuction.json",
|
||||
"./generated-artifacts/Forwarder.json",
|
||||
"./generated-artifacts/OrderMatcher.json",
|
||||
"./generated-artifacts/OrderValidator.json"
|
||||
],
|
||||
"exclude": ["./deploy/solc/solc_bin"]
|
||||
}
|
||||
|
20
contracts/interfaces/CHANGELOG.json
Normal file
20
contracts/interfaces/CHANGELOG.json
Normal file
@@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547040760,
|
||||
"version": "1.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1544741676,
|
||||
"version": "1.0.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
14
contracts/interfaces/CHANGELOG.md
Normal file
14
contracts/interfaces/CHANGELOG.md
Normal file
@@ -0,0 +1,14 @@
|
||||
<!--
|
||||
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
|
||||
Edit the package's CHANGELOG.json file only.
|
||||
-->
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.3 - _January 9, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.2 - _December 13, 2018_
|
||||
|
||||
* Dependencies updated
|
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
// solhint-disable
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "./IAuthorizable.sol";
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/Ownable/IOwnable.sol";
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract IAssetProxyDispatcher {
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./IExchangeCore.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-libs/contracts/libs/LibOrder.sol";
|
||||
|
@@ -15,7 +15,7 @@
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-libs/contracts/libs/LibOrder.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract ISignatureValidator {
|
||||
|
@@ -15,7 +15,7 @@
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract ITransactions {
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract IValidator {
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract IWallet {
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-libs/contracts/libs/LibOrder.sol";
|
||||
|
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@0x/contracts-interfaces",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -11,7 +10,8 @@
|
||||
"build": "yarn pre_build && tsc -b",
|
||||
"build:ci": "yarn build",
|
||||
"pre_build": "run-s compile generate_contract_wrappers",
|
||||
"compile": "sol-compiler --contracts-dir contracts",
|
||||
"compile": "sol-compiler",
|
||||
"watch": "sol-compiler -w",
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
@@ -30,8 +30,8 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/interfaces/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.19",
|
||||
"@0x/sol-compiler": "^1.1.16",
|
||||
"@0x/abi-gen": "^1.0.20",
|
||||
"@0x/sol-compiler": "^2.0.0",
|
||||
"@0x/tslint-config": "^2.0.0",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"shx": "^0.2.2",
|
||||
@@ -41,13 +41,13 @@
|
||||
"yargs": "^10.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.10",
|
||||
"@0x/contracts-libs": "^1.0.1",
|
||||
"@0x/contracts-utils": "^1.0.1",
|
||||
"@0x/types": "^1.4.1",
|
||||
"@0x/base-contract": "^3.0.11",
|
||||
"@0x/contracts-libs": "^1.0.3",
|
||||
"@0x/contracts-utils": "^1.0.3",
|
||||
"@0x/types": "^1.5.0",
|
||||
"@0x/typescript-typings": "^3.0.6",
|
||||
"@0x/utils": "^2.0.8",
|
||||
"@0x/web3-wrapper": "^3.2.1",
|
||||
"@0x/utils": "^2.1.1",
|
||||
"@0x/web3-wrapper": "^3.2.2",
|
||||
"ethereum-types": "^1.1.4",
|
||||
"lodash": "^4.17.5"
|
||||
},
|
||||
|
20
contracts/libs/CHANGELOG.json
Normal file
20
contracts/libs/CHANGELOG.json
Normal file
@@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547040760,
|
||||
"version": "1.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1544741676,
|
||||
"version": "1.0.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
14
contracts/libs/CHANGELOG.md
Normal file
14
contracts/libs/CHANGELOG.md
Normal file
@@ -0,0 +1,14 @@
|
||||
<!--
|
||||
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
|
||||
Edit the package's CHANGELOG.json file only.
|
||||
-->
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.3 - _January 9, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.2 - _December 13, 2018_
|
||||
|
||||
* Dependencies updated
|
@@ -18,5 +18,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"contracts": ["TestLibs", "LibOrder", "LibMath", "LibFillResults", "LibAbiEncoder", "LibEIP712"]
|
||||
"contracts": [
|
||||
"TestLibs",
|
||||
"LibOrder",
|
||||
"LibMath",
|
||||
"LibFillResults",
|
||||
"LibAbiEncoder",
|
||||
"LibEIP712",
|
||||
"LibAssetProxyErrors",
|
||||
"LibConstants"
|
||||
]
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./LibOrder.sol";
|
||||
|
84
contracts/libs/contracts/libs/LibAddressArray.sol
Normal file
84
contracts/libs/contracts/libs/LibAddressArray.sol
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol";
|
||||
|
||||
|
||||
library LibAddressArray {
|
||||
|
||||
/// @dev Append a new address to an array of addresses.
|
||||
/// The `addressArray` may need to be reallocated to make space
|
||||
/// for the new address. Because of this we return the resulting
|
||||
/// memory location of `addressArray`.
|
||||
/// @param addressToAppend Address to append.
|
||||
/// @return Array of addresses: [... addressArray, addressToAppend]
|
||||
function append(address[] memory addressArray, address addressToAppend)
|
||||
internal pure
|
||||
returns (address[])
|
||||
{
|
||||
// Get stats on address array and free memory
|
||||
uint256 freeMemPtr = 0;
|
||||
uint256 addressArrayBeginPtr = 0;
|
||||
uint256 addressArrayEndPtr = 0;
|
||||
uint256 addressArrayLength = addressArray.length;
|
||||
uint256 addressArrayMemSizeInBytes = 32 + (32 * addressArrayLength);
|
||||
assembly {
|
||||
freeMemPtr := mload(0x40)
|
||||
addressArrayBeginPtr := addressArray
|
||||
addressArrayEndPtr := add(addressArray, addressArrayMemSizeInBytes)
|
||||
}
|
||||
|
||||
// Cases for `freeMemPtr`:
|
||||
// `freeMemPtr` == `addressArrayEndPtr`: Nothing occupies memory after `addressArray`
|
||||
// `freeMemPtr` > `addressArrayEndPtr`: Some value occupies memory after `addressArray`
|
||||
// `freeMemPtr` < `addressArrayEndPtr`: Memory has not been managed properly.
|
||||
require(
|
||||
freeMemPtr >= addressArrayEndPtr,
|
||||
"INVALID_FREE_MEMORY_PTR"
|
||||
);
|
||||
|
||||
// If free memory begins at the end of `addressArray`
|
||||
// then we can append `addressToAppend` directly.
|
||||
// Otherwise, we must copy the array to free memory
|
||||
// before appending new values to it.
|
||||
if (freeMemPtr > addressArrayEndPtr) {
|
||||
LibBytes.memCopy(freeMemPtr, addressArrayBeginPtr, addressArrayMemSizeInBytes);
|
||||
assembly {
|
||||
addressArray := freeMemPtr
|
||||
addressArrayBeginPtr := addressArray
|
||||
}
|
||||
}
|
||||
|
||||
// Append `addressToAppend`
|
||||
addressArrayLength += 1;
|
||||
addressArrayMemSizeInBytes += 32;
|
||||
addressArrayEndPtr = addressArrayBeginPtr + addressArrayMemSizeInBytes;
|
||||
freeMemPtr = addressArrayEndPtr;
|
||||
assembly {
|
||||
// Store new array length
|
||||
mstore(addressArray, addressArrayLength)
|
||||
|
||||
// Update `freeMemPtr`
|
||||
mstore(0x40, freeMemPtr)
|
||||
}
|
||||
addressArray[addressArrayLength - 1] = addressToAppend;
|
||||
return addressArray;
|
||||
}
|
||||
}
|
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
// solhint-disable
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/// @dev This contract documents the revert reasons used in the AssetProxy contracts.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
// solhint-disable max-line-length
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract LibEIP712 {
|
||||
|
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
// solhint-disable
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/// @dev This contract documents the revert reasons used in the Exchange contract.
|
||||
|
152
contracts/libs/contracts/libs/LibExchangeSelectors.sol
Normal file
152
contracts/libs/contracts/libs/LibExchangeSelectors.sol
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract LibExchangeSelectors {
|
||||
|
||||
// solhint-disable max-line-length
|
||||
// allowedValidators
|
||||
bytes4 constant public ALLOWED_VALIDATORS_SELECTOR = 0x7b8e3514;
|
||||
bytes4 constant public ALLOWED_VALIDATORS_SELECTOR_GENERATOR = bytes4(keccak256("allowedValidators(address,address)"));
|
||||
|
||||
// assetProxies
|
||||
bytes4 constant public ASSET_PROXIES_SELECTOR = 0x3fd3c997;
|
||||
bytes4 constant public ASSET_PROXIES_SELECTOR_GENERATOR = bytes4(keccak256("assetProxies(bytes4)"));
|
||||
|
||||
// batchCancelOrders
|
||||
bytes4 constant public BATCH_CANCEL_ORDERS_SELECTOR = 0x4ac14782;
|
||||
bytes4 constant public BATCH_CANCEL_ORDERS_SELECTOR_GENERATOR = bytes4(keccak256("batchCancelOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[])"));
|
||||
|
||||
// batchFillOrKillOrders
|
||||
bytes4 constant public BATCH_FILL_OR_KILL_ORDERS_SELECTOR = 0x4d0ae546;
|
||||
bytes4 constant public BATCH_FILL_OR_KILL_ORDERS_SELECTOR_GENERATOR = bytes4(keccak256("batchFillOrKillOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256[],bytes[])"));
|
||||
|
||||
// batchFillOrders
|
||||
bytes4 constant public BATCH_FILL_ORDERS_SELECTOR = 0x297bb70b;
|
||||
bytes4 constant public BATCH_FILL_ORDERS_SELECTOR_GENERATOR = bytes4(keccak256("batchFillOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256[],bytes[])"));
|
||||
|
||||
// batchFillOrdersNoThrow
|
||||
bytes4 constant public BATCH_FILL_ORDERS_NO_THROW_SELECTOR = 0x50dde190;
|
||||
bytes4 constant public BATCH_FILL_ORDERS_NO_THROW_SELECTOR_GENERATOR = bytes4(keccak256("batchFillOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256[],bytes[])"));
|
||||
|
||||
// cancelOrder
|
||||
bytes4 constant public CANCEL_ORDER_SELECTOR = 0xd46b02c3;
|
||||
bytes4 constant public CANCEL_ORDER_SELECTOR_GENERATOR = bytes4(keccak256("cancelOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes))"));
|
||||
|
||||
// cancelOrdersUpTo
|
||||
bytes4 constant public CANCEL_ORDERS_UP_TO_SELECTOR = 0x4f9559b1;
|
||||
bytes4 constant public CANCEL_ORDERS_UP_TO_SELECTOR_GENERATOR = bytes4(keccak256("cancelOrdersUpTo(uint256)"));
|
||||
|
||||
// cancelled
|
||||
bytes4 constant public CANCELLED_SELECTOR = 0x2ac12622;
|
||||
bytes4 constant public CANCELLED_SELECTOR_GENERATOR = bytes4(keccak256("cancelled(bytes32)"));
|
||||
|
||||
// currentContextAddress
|
||||
bytes4 constant public CURRENT_CONTEXT_ADDRESS_SELECTOR = 0xeea086ba;
|
||||
bytes4 constant public CURRENT_CONTEXT_ADDRESS_SELECTOR_GENERATOR = bytes4(keccak256("currentContextAddress()"));
|
||||
|
||||
// executeTransaction
|
||||
bytes4 constant public EXECUTE_TRANSACTION_SELECTOR = 0xbfc8bfce;
|
||||
bytes4 constant public EXECUTE_TRANSACTION_SELECTOR_GENERATOR = bytes4(keccak256("executeTransaction(uint256,address,bytes,bytes)"));
|
||||
|
||||
// fillOrKillOrder
|
||||
bytes4 constant public FILL_OR_KILL_ORDER_SELECTOR = 0x64a3bc15;
|
||||
bytes4 constant public FILL_OR_KILL_ORDER_SELECTOR_GENERATOR = bytes4(keccak256("fillOrKillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)"));
|
||||
|
||||
// fillOrder
|
||||
bytes4 constant public FILL_ORDER_SELECTOR = 0xb4be83d5;
|
||||
bytes4 constant public FILL_ORDER_SELECTOR_GENERATOR = bytes4(keccak256("fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)"));
|
||||
|
||||
// fillOrderNoThrow
|
||||
bytes4 constant public FILL_ORDER_NO_THROW_SELECTOR = 0x3e228bae;
|
||||
bytes4 constant public FILL_ORDER_NO_THROW_SELECTOR_GENERATOR = bytes4(keccak256("fillOrderNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)"));
|
||||
|
||||
// filled
|
||||
bytes4 constant public FILLED_SELECTOR = 0x288cdc91;
|
||||
bytes4 constant public FILLED_SELECTOR_GENERATOR = bytes4(keccak256("filled(bytes32)"));
|
||||
|
||||
// getAssetProxy
|
||||
bytes4 constant public GET_ASSET_PROXY_SELECTOR = 0x60704108;
|
||||
bytes4 constant public GET_ASSET_PROXY_SELECTOR_GENERATOR = bytes4(keccak256("getAssetProxy(bytes4)"));
|
||||
|
||||
// getOrderInfo
|
||||
bytes4 constant public GET_ORDER_INFO_SELECTOR = 0xc75e0a81;
|
||||
bytes4 constant public GET_ORDER_INFO_SELECTOR_GENERATOR = bytes4(keccak256("getOrderInfo((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes))"));
|
||||
|
||||
// getOrdersInfo
|
||||
bytes4 constant public GET_ORDERS_INFO_SELECTOR = 0x7e9d74dc;
|
||||
bytes4 constant public GET_ORDERS_INFO_SELECTOR_GENERATOR = bytes4(keccak256("getOrdersInfo((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[])"));
|
||||
|
||||
// isValidSignature
|
||||
bytes4 constant public IS_VALID_SIGNATURE_SELECTOR = 0x93634702;
|
||||
bytes4 constant public IS_VALID_SIGNATURE_SELECTOR_GENERATOR = bytes4(keccak256("isValidSignature(bytes32,address,bytes)"));
|
||||
|
||||
// marketBuyOrders
|
||||
bytes4 constant public MARKET_BUY_ORDERS_SELECTOR = 0xe5fa431b;
|
||||
bytes4 constant public MARKET_BUY_ORDERS_SELECTOR_GENERATOR = bytes4(keccak256("marketBuyOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256,bytes[])"));
|
||||
|
||||
// marketBuyOrdersNoThrow
|
||||
bytes4 constant public MARKET_BUY_ORDERS_NO_THROW_SELECTOR = 0xa3e20380;
|
||||
bytes4 constant public MARKET_BUY_ORDERS_NO_THROW_SELECTOR_GENERATOR = bytes4(keccak256("marketBuyOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256,bytes[])"));
|
||||
|
||||
// marketSellOrders
|
||||
bytes4 constant public MARKET_SELL_ORDERS_SELECTOR = 0x7e1d9808;
|
||||
bytes4 constant public MARKET_SELL_ORDERS_SELECTOR_GENERATOR = bytes4(keccak256("marketSellOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256,bytes[])"));
|
||||
|
||||
// marketSellOrdersNoThrow
|
||||
bytes4 constant public MARKET_SELL_ORDERS_NO_THROW_SELECTOR = 0xdd1c7d18;
|
||||
bytes4 constant public MARKET_SELL_ORDERS_NO_THROW_SELECTOR_GENERATOR = bytes4(keccak256("marketSellOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256,bytes[])"));
|
||||
|
||||
// matchOrders
|
||||
bytes4 constant public MATCH_ORDERS_SELECTOR = 0x3c28d861;
|
||||
bytes4 constant public MATCH_ORDERS_SELECTOR_GENERATOR = bytes4(keccak256("matchOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes,bytes)"));
|
||||
|
||||
// orderEpoch
|
||||
bytes4 constant public ORDER_EPOCH_SELECTOR = 0xd9bfa73e;
|
||||
bytes4 constant public ORDER_EPOCH_SELECTOR_GENERATOR = bytes4(keccak256("orderEpoch(address,address)"));
|
||||
|
||||
// owner
|
||||
bytes4 constant public OWNER_SELECTOR = 0x8da5cb5b;
|
||||
bytes4 constant public OWNER_SELECTOR_GENERATOR = bytes4(keccak256("owner()"));
|
||||
|
||||
// preSign
|
||||
bytes4 constant public PRE_SIGN_SELECTOR = 0x3683ef8e;
|
||||
bytes4 constant public PRE_SIGN_SELECTOR_GENERATOR = bytes4(keccak256("preSign(bytes32,address,bytes)"));
|
||||
|
||||
// preSigned
|
||||
bytes4 constant public PRE_SIGNED_SELECTOR = 0x82c174d0;
|
||||
bytes4 constant public PRE_SIGNED_SELECTOR_GENERATOR = bytes4(keccak256("preSigned(bytes32,address)"));
|
||||
|
||||
// registerAssetProxy
|
||||
bytes4 constant public REGISTER_ASSET_PROXY_SELECTOR = 0xc585bb93;
|
||||
bytes4 constant public REGISTER_ASSET_PROXY_SELECTOR_GENERATOR = bytes4(keccak256("registerAssetProxy(address)"));
|
||||
|
||||
// setSignatureValidatorApproval
|
||||
bytes4 constant public SET_SIGNATURE_VALIDATOR_APPROVAL_SELECTOR = 0x77fcce68;
|
||||
bytes4 constant public SET_SIGNATURE_VALIDATOR_APPROVAL_SELECTOR_GENERATOR = bytes4(keccak256("setSignatureValidatorApproval(address,bool)"));
|
||||
|
||||
// transactions
|
||||
bytes4 constant public TRANSACTIONS_SELECTOR = 0x642f2eaf;
|
||||
bytes4 constant public TRANSACTIONS_SELECTOR_GENERATOR = bytes4(keccak256("transactions(bytes32)"));
|
||||
|
||||
// transferOwnership
|
||||
bytes4 constant public TRANSFER_OWNERSHIP_SELECTOR = 0xf2fde38b;
|
||||
bytes4 constant public TRANSFER_OWNERSHIP_SELECTOR_GENERATOR = bytes4(keccak256("transferOwnership(address)"));
|
||||
}
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/SafeMath/SafeMath.sol";
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/SafeMath/SafeMath.sol";
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "./LibEIP712.sol";
|
||||
|
||||
|
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@0x/contracts-libs",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -20,7 +19,8 @@
|
||||
"test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html",
|
||||
"test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
||||
"compile": "sol-compiler --contracts-dir contracts",
|
||||
"compile": "sol-compiler",
|
||||
"watch": "sol-compiler -w",
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
@@ -44,12 +44,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/libs/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.19",
|
||||
"@0x/contracts-test-utils": "^1.0.2",
|
||||
"@0x/dev-utils": "^1.0.21",
|
||||
"@0x/sol-compiler": "^1.1.16",
|
||||
"@0x/sol-cov": "^2.1.16",
|
||||
"@0x/subproviders": "^2.1.8",
|
||||
"@0x/abi-gen": "^1.0.20",
|
||||
"@0x/contracts-test-utils": "^1.0.3",
|
||||
"@0x/dev-utils": "^1.0.22",
|
||||
"@0x/sol-compiler": "^2.0.0",
|
||||
"@0x/sol-cov": "^2.1.17",
|
||||
"@0x/subproviders": "^2.1.9",
|
||||
"@0x/tslint-config": "^2.0.0",
|
||||
"@types/bn.js": "^4.11.0",
|
||||
"@types/lodash": "4.14.104",
|
||||
@@ -64,21 +64,20 @@
|
||||
"mocha": "^4.1.0",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"shx": "^0.2.2",
|
||||
"solc": "^0.4.24",
|
||||
"solhint": "^1.4.1",
|
||||
"tslint": "5.11.0",
|
||||
"typescript": "3.0.1",
|
||||
"yargs": "^10.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.10",
|
||||
"@0x/contracts-multisig": "^1.0.1",
|
||||
"@0x/contracts-utils": "^1.0.1",
|
||||
"@0x/order-utils": "^3.0.7",
|
||||
"@0x/types": "^1.4.1",
|
||||
"@0x/base-contract": "^3.0.11",
|
||||
"@0x/contracts-multisig": "^1.0.3",
|
||||
"@0x/contracts-utils": "^1.0.3",
|
||||
"@0x/order-utils": "^3.1.0",
|
||||
"@0x/types": "^1.5.0",
|
||||
"@0x/typescript-typings": "^3.0.6",
|
||||
"@0x/utils": "^2.0.8",
|
||||
"@0x/web3-wrapper": "^3.2.1",
|
||||
"@0x/utils": "^2.1.1",
|
||||
"@0x/web3-wrapper": "^3.2.2",
|
||||
"@types/js-combinatorics": "^0.5.29",
|
||||
"bn.js": "^4.11.8",
|
||||
"ethereum-types": "^1.1.4",
|
||||
|
@@ -1 +1,20 @@
|
||||
[]
|
||||
[
|
||||
{
|
||||
"timestamp": 1547040760,
|
||||
"version": "1.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1544741676,
|
||||
"version": "1.0.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
14
contracts/multisig/CHANGELOG.md
Normal file
14
contracts/multisig/CHANGELOG.md
Normal file
@@ -0,0 +1,14 @@
|
||||
<!--
|
||||
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
|
||||
Edit the package's CHANGELOG.json file only.
|
||||
-->
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.3 - _January 9, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.2 - _December 13, 2018_
|
||||
|
||||
* Dependencies updated
|
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@0x/contracts-multisig",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -20,7 +19,8 @@
|
||||
"test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html",
|
||||
"test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
||||
"compile": "sol-compiler --contracts-dir contracts",
|
||||
"compile": "sol-compiler",
|
||||
"watch": "sol-compiler -w",
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../packages/abi-gen-templates/contract.handlebars --partials '../../packages/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
@@ -44,12 +44,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/multisig/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.19",
|
||||
"@0x/contracts-test-utils": "^1.0.2",
|
||||
"@0x/dev-utils": "^1.0.21",
|
||||
"@0x/sol-compiler": "^1.1.16",
|
||||
"@0x/sol-cov": "^2.1.16",
|
||||
"@0x/subproviders": "^2.1.8",
|
||||
"@0x/abi-gen": "^1.0.20",
|
||||
"@0x/contracts-test-utils": "^1.0.3",
|
||||
"@0x/dev-utils": "^1.0.22",
|
||||
"@0x/sol-compiler": "^2.0.0",
|
||||
"@0x/sol-cov": "^2.1.17",
|
||||
"@0x/subproviders": "^2.1.9",
|
||||
"@0x/tslint-config": "^2.0.0",
|
||||
"@types/bn.js": "^4.11.0",
|
||||
"@types/ethereumjs-abi": "^0.6.0",
|
||||
@@ -64,19 +64,18 @@
|
||||
"mocha": "^4.1.0",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"shx": "^0.2.2",
|
||||
"solc": "^0.4.24",
|
||||
"solhint": "^1.4.1",
|
||||
"tslint": "5.11.0",
|
||||
"typescript": "3.0.1",
|
||||
"yargs": "^10.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.10",
|
||||
"@0x/order-utils": "^3.0.7",
|
||||
"@0x/types": "^1.4.1",
|
||||
"@0x/base-contract": "^3.0.11",
|
||||
"@0x/order-utils": "^3.1.0",
|
||||
"@0x/types": "^1.5.0",
|
||||
"@0x/typescript-typings": "^3.0.6",
|
||||
"@0x/utils": "^2.0.8",
|
||||
"@0x/web3-wrapper": "^3.2.1",
|
||||
"@0x/utils": "^2.1.1",
|
||||
"@0x/web3-wrapper": "^3.2.2",
|
||||
"ethereum-types": "^1.1.4",
|
||||
"lodash": "^4.17.5"
|
||||
},
|
||||
|
2
contracts/multisig/src/index.ts
Normal file
2
contracts/multisig/src/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './artifacts';
|
||||
export * from './wrappers';
|
@@ -1,120 +1,28 @@
|
||||
[
|
||||
{
|
||||
"name": "MultiAssetProxy",
|
||||
"version": "1.0.0",
|
||||
"version": "2.2.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add MultiAssetProxy implementation",
|
||||
"pr": 1224
|
||||
"note": "Added LibAddressArray",
|
||||
"pr": 1383
|
||||
},
|
||||
{
|
||||
"note": "Add validation and comments to MultiAssetProxy",
|
||||
"pr": 1455
|
||||
},
|
||||
{
|
||||
"note": "Move OrderValidator to extensions",
|
||||
"pr": 1464
|
||||
}
|
||||
]
|
||||
],
|
||||
"timestamp": 1547040760
|
||||
},
|
||||
{
|
||||
"name": "OrderValidator",
|
||||
"version": "1.0.0",
|
||||
"timestamp": 1544741676,
|
||||
"version": "2.1.59",
|
||||
"changes": [
|
||||
{
|
||||
"note": "remove `getApproved` check from ERC721 approval query",
|
||||
"pr": 1149
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Forwarder",
|
||||
"version": "1.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Round up when calculating remaining amounts in marketBuy functions",
|
||||
"pr": 1162,
|
||||
"networks": {
|
||||
"1": "0x5468a1dc173652ee28d249c271fa9933144746b1",
|
||||
"3": "0x2240dab907db71e64d3e0dba4800c83b5c502d4e",
|
||||
"42": "0x17992e4ffb22730138e4b62aaa6367fa9d3699a6"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Forwarder",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x7afc2d5107af94c462a194d2c21b5bdd238709d6",
|
||||
"3": "0x3983e204b12b3c02fb0638caf2cd406a62e0ead3",
|
||||
"42": "0xd85e2fa7e7e252b27b01bf0d65c946959d2f45b8"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OrderValidator",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x9463e518dea6810309563c81d5266c1b1d149138",
|
||||
"3": "0x90431a90516ab49af23a0530e04e8c7836e7122f",
|
||||
"42": "0xb389da3d204b412df2f75c6afb3d0a7ce0bc283d"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Exchange",
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x4f833a24e1f95d70f028921e27040ca56e09ab0b",
|
||||
"3": "0x4530c0483a1633c7a1c97d2c53721caff2caaaaf",
|
||||
"42": "0x35dd2932454449b14cee11a94d3674a936d5d7b2"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ERC20Proxy",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x2240dab907db71e64d3e0dba4800c83b5c502d4e",
|
||||
"3": "0xb1408f4c245a23c31b98d2c626777d4c0d766caa",
|
||||
"42": "0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ERC721Proxy",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x208e41fb445f1bb1b6780d58356e81405f3e6127",
|
||||
"3": "0xe654aac058bfbf9f83fcaee7793311dd82f6ddb4",
|
||||
"42": "0x2a9127c745688a165106c11cd4d647d2220af821"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AssetProxyOwner",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x17992e4ffb22730138e4b62aaa6367fa9d3699a6",
|
||||
"3": "0xf5fa5b5fed2727a0e44ac67f6772e97977aa358b",
|
||||
"42": "0x2c824d2882baa668e0d5202b1e7f2922278703f8"
|
||||
}
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
16
contracts/protocol/CHANGELOG.md
Normal file
16
contracts/protocol/CHANGELOG.md
Normal file
@@ -0,0 +1,16 @@
|
||||
<!--
|
||||
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
|
||||
Edit the package's CHANGELOG.json file only.
|
||||
-->
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.2.0 - _January 9, 2019_
|
||||
|
||||
* Added LibAddressArray (#1383)
|
||||
* Add validation and comments to MultiAssetProxy (#1455)
|
||||
* Move OrderValidator to extensions (#1464)
|
||||
|
||||
## v2.1.59 - _December 13, 2018_
|
||||
|
||||
* Dependencies updated
|
92
contracts/protocol/DEPLOYS.json
Normal file
92
contracts/protocol/DEPLOYS.json
Normal file
@@ -0,0 +1,92 @@
|
||||
[
|
||||
{
|
||||
"name": "MultiAssetProxy",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add MultiAssetProxy implementation",
|
||||
"pr": 1224
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OrderValidator",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "remove `getApproved` check from ERC721 approval query",
|
||||
"pr": 1149
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OrderValidator",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x9463e518dea6810309563c81d5266c1b1d149138",
|
||||
"3": "0x90431a90516ab49af23a0530e04e8c7836e7122f",
|
||||
"42": "0xb389da3d204b412df2f75c6afb3d0a7ce0bc283d"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Exchange",
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x4f833a24e1f95d70f028921e27040ca56e09ab0b",
|
||||
"3": "0x4530c0483a1633c7a1c97d2c53721caff2caaaaf",
|
||||
"42": "0x35dd2932454449b14cee11a94d3674a936d5d7b2"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ERC20Proxy",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x2240dab907db71e64d3e0dba4800c83b5c502d4e",
|
||||
"3": "0xb1408f4c245a23c31b98d2c626777d4c0d766caa",
|
||||
"42": "0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ERC721Proxy",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x208e41fb445f1bb1b6780d58356e81405f3e6127",
|
||||
"3": "0xe654aac058bfbf9f83fcaee7793311dd82f6ddb4",
|
||||
"42": "0x2a9127c745688a165106c11cd4d647d2220af821"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AssetProxyOwner",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x17992e4ffb22730138e4b62aaa6367fa9d3699a6",
|
||||
"3": "0xf5fa5b5fed2727a0e44ac67f6772e97977aa358b",
|
||||
"42": "0x2c824d2882baa668e0d5202b1e7f2922278703f8"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@@ -25,7 +25,6 @@
|
||||
"Exchange",
|
||||
"MixinAuthorizable",
|
||||
"MultiAssetProxy",
|
||||
"OrderValidator",
|
||||
"TestAssetProxyOwner",
|
||||
"TestAssetProxyDispatcher",
|
||||
"TestExchangeInternals",
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/Ownable/Ownable.sol";
|
||||
import "./mixins/MAuthorizable.sol";
|
||||
|
@@ -33,6 +33,9 @@ contract MultiAssetProxy is
|
||||
function ()
|
||||
external
|
||||
{
|
||||
// NOTE: The below assembly assumes that clients do some input validation and that the input is properly encoded according to the AbiV2 specification.
|
||||
// It is technically possible for inputs with very large lengths and offsets to cause overflows. However, this would make the calldata prohibitively
|
||||
// expensive and we therefore do not check for overflows in these scenarios.
|
||||
assembly {
|
||||
// The first 4 bytes of calldata holds the function selector
|
||||
let selector := and(calldataload(0), 0xffffffff00000000000000000000000000000000000000000000000000000000)
|
||||
@@ -145,7 +148,7 @@ contract MultiAssetProxy is
|
||||
let nestedAssetDataLen := calldataload(sub(nestedAssetDataContentsStart, 32))
|
||||
|
||||
// Revert if number of elements in `amounts` differs from number of elements in `nestedAssetData`
|
||||
if iszero(eq(amountsLen, nestedAssetDataLen)) {
|
||||
if sub(amountsLen, nestedAssetDataLen) {
|
||||
// Revert with `Error("LENGTH_MISMATCH")`
|
||||
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
|
||||
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
|
||||
@@ -181,8 +184,11 @@ contract MultiAssetProxy is
|
||||
let amountsElement := calldataload(add(amountsContentsStart, i))
|
||||
let totalAmount := mul(amountsElement, amount)
|
||||
|
||||
// Revert if multiplication resulted in an overflow
|
||||
if iszero(eq(div(totalAmount, amount), amountsElement)) {
|
||||
// Revert if `amount` != 0 and multiplication resulted in an overflow
|
||||
if iszero(or(
|
||||
iszero(amount),
|
||||
eq(div(totalAmount, amount), amountsElement)
|
||||
)) {
|
||||
// Revert with `Error("UINT256_OVERFLOW")`
|
||||
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
|
||||
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
|
||||
@@ -230,7 +236,7 @@ contract MultiAssetProxy is
|
||||
|
||||
// Only load `assetProxy` if `currentAssetProxyId` does not equal `assetProxyId`
|
||||
// We do not need to check if `currentAssetProxyId` is 0 since `assetProxy` is also initialized to 0
|
||||
if iszero(eq(currentAssetProxyId, assetProxyId)) {
|
||||
if sub(currentAssetProxyId, assetProxyId) {
|
||||
// Update `assetProxyId`
|
||||
assetProxyId := currentAssetProxyId
|
||||
// To lookup a value in a mapping, we load from the storage location keccak256(k, p),
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-interfaces/contracts/protocol/AssetProxy/IAuthorizable.sol";
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/Ownable/Ownable.sol";
|
||||
import "./mixins/MAssetProxyDispatcher.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/ReentrancyGuard/ReentrancyGuard.sol";
|
||||
|
@@ -11,7 +11,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/ReentrancyGuard/ReentrancyGuard.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol";
|
||||
import "@0x/contracts-utils/contracts/utils/ReentrancyGuard/ReentrancyGuard.sol";
|
||||
|
@@ -15,7 +15,7 @@
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-libs/contracts/libs/LibExchangeErrors.sol";
|
||||
import "./mixins/MSignatureValidator.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/utils/ReentrancyGuard/ReentrancyGuard.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "@0x/contracts-interfaces/contracts/protocol/Exchange/IAssetProxyDispatcher.sol";
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-libs/contracts/libs/LibOrder.sol";
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user