Compare commits
	
		
			632 Commits
		
	
	
		
			@0x/abi-ge
			...
			@0x/abi-ge
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | f394d7dba9 | ||
|  | ca595cd8cf | ||
|  | ec807120c3 | ||
|  | a5654debeb | ||
|  | 0869c0d8b0 | ||
|  | b456c3f953 | ||
|  | 8297d68166 | ||
|  | 18ce6797e0 | ||
|  | c1009d440e | ||
|  | 89ee6fe6db | ||
|  | 38a12475bc | ||
|  | 9a800264a2 | ||
|  | 8ce390be3c | ||
|  | 5ac7ff7084 | ||
|  | e682b82ca8 | ||
|  | 7cd1fd0aaa | ||
|  | 8cd99c5a40 | ||
|  | ad83312009 | ||
|  | 9e3b1fe333 | ||
|  | c3f42995f9 | ||
|  | 3d3a02c892 | ||
|  | 06bec227ad | ||
|  | 5d7803323c | ||
|  | 4303f9a025 | ||
|  | fe4c5434fa | ||
|  | 9325bb70c5 | ||
|  | b164557165 | ||
|  | 424f984ea8 | ||
|  | 78c704e3d1 | ||
|  | 50f1a8fbd8 | ||
|  | 0f90b7b5da | ||
|  | bec4384a5d | ||
|  | f361efae5a | ||
|  | 76ca2116ab | ||
|  | 33d8646dc5 | ||
|  | 3cb5190bc6 | ||
|  | 5bba06bef8 | ||
|  | dd3f672a35 | ||
|  | 25ef3b8445 | ||
|  | 7eb2d290d8 | ||
|  | 678762910b | ||
|  | da28a542c7 | ||
|  | 92602d33ad | ||
|  | 03f04f4bb3 | ||
|  | 0d4dd5ff0d | ||
|  | 884864cc58 | ||
|  | 7c199d83be | ||
|  | 5b4c29c4bb | ||
|  | f97ee80955 | ||
|  | 547322ae63 | ||
|  | db74db622e | ||
|  | 57318c0041 | ||
|  | 4eb0767834 | ||
|  | 92bb7808ce | ||
|  | abfe7d1613 | ||
|  | 6c72239365 | ||
|  | 8001daad8c | ||
|  | 73a38ab4f4 | ||
|  | 281c207921 | ||
|  | ae531eef5f | ||
|  | d8b11238e6 | ||
|  | d36eb04ae8 | ||
|  | b97ba35279 | ||
|  | 46efe92a72 | ||
|  | 9cc27c7d1b | ||
|  | 7d3396f9c5 | ||
|  | 918ef13714 | ||
|  | 9d12462893 | ||
|  | ed44e16a95 | ||
|  | dadab94644 | ||
|  | 7ec232a470 | ||
|  | dc3569392c | ||
|  | 11999cd407 | ||
|  | f786f8a7f6 | ||
|  | aab39e6ae0 | ||
|  | 31d3968649 | ||
|  | 2cd0b01019 | ||
|  | a6bc0db896 | ||
|  | 7cba95b523 | ||
|  | 1b976130ce | ||
|  | e9babc5a94 | ||
|  | c8d0ff846c | ||
|  | db1e9769d0 | ||
|  | 4b038b07ed | ||
|  | 4c17c142f9 | ||
|  | 65b2fa13ac | ||
|  | c375199daa | ||
|  | 805131cf1e | ||
|  | 6f64115561 | ||
|  | 0aadb789a5 | ||
|  | 26ee4d626c | ||
|  | a8939d3eda | ||
|  | 048e48b03a | ||
|  | c2f34baee0 | ||
|  | 8961b476ef | ||
|  | 58e08335b5 | ||
|  | ea8fc1d93f | ||
|  | 2968dfb2ae | ||
|  | 24783107ba | ||
|  | 365c056b0f | ||
|  | 88a7d9cca8 | ||
|  | d8cf9d54aa | ||
|  | df746c5ff4 | ||
|  | aa29526ae4 | ||
|  | f0b5616aba | ||
|  | 2eca95df00 | ||
|  | f560c2e66a | ||
|  | 5e19496e32 | ||
|  | aeadaba005 | ||
|  | 8dfda9ffdd | ||
|  | 91992bb034 | ||
|  | 34a93857a0 | ||
|  | fbda096aa9 | ||
|  | 24a26aef70 | ||
|  | ec7f9d8a63 | ||
|  | cc7dec7a99 | ||
|  | 46384ce80d | ||
|  | 5aeb626045 | ||
|  | d2a27f1a48 | ||
|  | f07c67202f | ||
|  | 3a3658708a | ||
|  | f3c5d19246 | ||
|  | c66d8f202a | ||
|  | ec641c171d | ||
|  | 773d624365 | ||
|  | 25bd97a014 | ||
|  | 5dd9e28f72 | ||
|  | cc1ef6f268 | ||
|  | 967e361da3 | ||
|  | 398097900c | ||
|  | b86473f3c7 | ||
|  | 3d361c6b4a | ||
|  | 3346024ea7 | ||
|  | 2fecf6c80b | ||
|  | 183b4fb7ee | ||
|  | 0e2afc5dcb | ||
|  | 91aa716c07 | ||
|  | 9977626de0 | ||
|  | 8bb3fb5bb3 | ||
|  | 6d7adb277e | ||
|  | fef1bd13b5 | ||
|  | 910bba9976 | ||
|  | cd2d756717 | ||
|  | 0a47d89963 | ||
|  | 65e5b09cd1 | ||
|  | 6f3cee1a1e | ||
|  | c43d4bbf71 | ||
|  | b7337410aa | ||
|  | 10b7d7da3f | ||
|  | 97a8c6e5af | ||
|  | e69d2bb54a | ||
|  | ead8099109 | ||
|  | 9d455b2bca | ||
|  | 1e6e74878f | ||
|  | cbcede3b63 | ||
|  | 98fd731485 | ||
|  | 9ca319b4ea | ||
|  | ff8fabf49e | ||
|  | 1e00f68941 | ||
|  | 6c79edd3b2 | ||
|  | b79bc6bab9 | ||
|  | c59d886662 | ||
|  | e39dce6159 | ||
|  | 620c66fb4c | ||
|  | 3af91d54cb | ||
|  | 1fe1bcff98 | ||
|  | c58c12c5b3 | ||
|  | 1aeea39eb3 | ||
|  | d3fbf020de | ||
|  | 8ce8bee76f | ||
|  | dcf4eb2aaf | ||
|  | 88ff38eca6 | ||
|  | bf0d90d079 | ||
|  | c4d9ef9f83 | ||
|  | 37bce53683 | ||
|  | 05d50b62c9 | ||
|  | eb2fb7f790 | ||
|  | d280ccb3c4 | ||
|  | a569815840 | ||
|  | 9e41c3093b | ||
|  | 9dbc9a8ad9 | ||
|  | c940157814 | ||
|  | 4f19875a58 | ||
|  | dcbadb2386 | ||
|  | 405a7b2037 | ||
|  | e69ad24737 | ||
|  | a31056a4ec | ||
|  | d41dddddcd | ||
|  | 251ae50d3e | ||
|  | 4ccd2d4955 | ||
|  | dfb79e0998 | ||
|  | 590055e2ba | ||
|  | f388751a97 | ||
|  | 53136caaa4 | ||
|  | dd20d8d6de | ||
|  | a977957946 | ||
|  | 8974fcabe3 | ||
|  | aff8e1e025 | ||
|  | 10d767c5ab | ||
|  | 77484dc69e | ||
|  | 185e2342d9 | ||
|  | 54f4727adc | ||
|  | 6e0f982163 | ||
|  | 43072ef80d | ||
|  | 7618e63f49 | ||
|  | 542255332d | ||
|  | 6d6e7e1468 | ||
|  | 0ff88d5c21 | ||
|  | 092e35bae3 | ||
|  | ac82b2622c | ||
|  | 7197cb57cd | ||
|  | 030d66cb63 | ||
|  | d414e6a7c4 | ||
|  | 30f9c94620 | ||
|  | b6b618e5ce | ||
|  | 0bb8887027 | ||
|  | fabfdd0aa2 | ||
|  | 8f8336b344 | ||
|  | d10659f986 | ||
|  | e853555165 | ||
|  | 2ce09d73ac | ||
|  | 14f48a5f4f | ||
|  | 8da4e4a830 | ||
|  | 88ae8311c8 | ||
|  | eabf6a466a | ||
|  | 989f691d06 | ||
|  | 52a3dae7cb | ||
|  | 8a6dfacf71 | ||
|  | 19ca6c13ad | ||
|  | 9196f122dd | ||
|  | 55e3d81c58 | ||
|  | 80caa16718 | ||
|  | ddc5aaacdb | ||
|  | 38825865cc | ||
|  | 157b2efa1d | ||
|  | 212a2d229a | ||
|  | ccb89fb26a | ||
|  | 3a0b0c0973 | ||
|  | c159ed9ebb | ||
|  | e37dbcc273 | ||
|  | 841e660b1f | ||
|  | 391aba5f37 | ||
|  | f5d30f4a07 | ||
|  | 230cf7dfb7 | ||
|  | 8734b70f83 | ||
|  | ff9a2b2d9a | ||
|  | a41dab2922 | ||
|  | f4504106a1 | ||
|  | 1a5b8041c7 | ||
|  | 1e2170f8bb | ||
|  | 0a4a973a7f | ||
|  | 67137cadac | ||
|  | ead4afa06b | ||
|  | e39ef95191 | ||
|  | 3d7585671f | ||
|  | 44806106db | ||
|  | 6a8197a4e8 | ||
|  | 4d4b4e0f2b | ||
|  | 82da33d742 | ||
|  | 1c6130a492 | ||
|  | dabe5e939f | ||
|  | b4ac6d3439 | ||
|  | d0ea74e180 | ||
|  | a5f77f3964 | ||
|  | 9401bb53e8 | ||
|  | 347c6d02cf | ||
|  | 64a0080616 | ||
|  | 288a7d4cea | ||
|  | 1207b68f57 | ||
|  | 2b82187fe0 | ||
|  | 3e2dbfc83c | ||
|  | 6691f490bc | ||
|  | a7db900e51 | ||
|  | cfa2a90dae | ||
|  | feebb45e9d | ||
|  | 13a2f3a330 | ||
|  | 1da8801084 | ||
|  | 7a7b17c4f3 | ||
|  | 2afb06de13 | ||
|  | ac771e2865 | ||
|  | 4b09204936 | ||
|  | e4a5518a7c | ||
|  | e83507ba98 | ||
|  | 6e5b77edb2 | ||
|  | 98167da8fa | ||
|  | 11d5fec59b | ||
|  | ed02f4ca88 | ||
|  | e7c612971d | ||
|  | 242a2e21b5 | ||
|  | 92a1e5413b | ||
|  | e1ab9aa690 | ||
|  | 222f7e6fd4 | ||
|  | 59001f827b | ||
|  | 549bfe98f1 | ||
|  | 64e3b6f5ee | ||
|  | 2fdc0426ff | ||
|  | e6c70fda66 | ||
|  | 50da1354f3 | ||
|  | e503cacf57 | ||
|  | 6a1e0edc78 | ||
|  | 048f5c2771 | ||
|  | d9378e9a8f | ||
|  | f77aaaf2e0 | ||
|  | 380835b151 | ||
|  | 857d91df85 | ||
|  | cd9a6b0de7 | ||
|  | 86333f4928 | ||
|  | d1975bd5dd | ||
|  | 08b9f27eac | ||
|  | 5b2cf8a776 | ||
|  | 7394106880 | ||
|  | 9134a7ae1e | ||
|  | c617e9f483 | ||
|  | 545fcef716 | ||
|  | e20fa3a1bf | ||
|  | 9d01b47d5b | ||
|  | fa4c34df41 | ||
|  | 9f8ab4d626 | ||
|  | 1971c9cecd | ||
|  | 82f730831d | ||
|  | 035167e5b7 | ||
|  | 323fb0a965 | ||
|  | 45aacf122f | ||
|  | 5dcf7919fc | ||
|  | f15560bd89 | ||
|  | bf3ae730d6 | ||
|  | 92ce258bb4 | ||
|  | 5810e7df82 | ||
|  | f2cbf4a561 | ||
|  | 0c8bb2e675 | ||
|  | f51c4f9617 | ||
|  | 5345f7c983 | ||
|  | 7d9e43b2e1 | ||
|  | 570c1e1809 | ||
|  | 720d335b09 | ||
|  | f0ecda1a48 | ||
|  | 4ed111a7d4 | ||
|  | fc257523c7 | ||
|  | 9775f8d83c | ||
|  | 01a1b19556 | ||
|  | bd228034fd | ||
|  | 2672a5c59f | ||
|  | 5f383430eb | ||
|  | 66ec3e9f4d | ||
|  | c269c427a6 | ||
|  | 212855ebd8 | ||
|  | 8f78945a73 | ||
|  | 86d50cf597 | ||
|  | 8986d506a5 | ||
|  | 3d2c945c35 | ||
|  | 8206a3969f | ||
|  | 43afe67593 | ||
|  | ecf939f8c8 | ||
|  | f0c4ccfa1e | ||
|  | 718d48b7d5 | ||
|  | d5e88677ae | ||
|  | b1cfdc7a6a | ||
|  | 5c5f815b20 | ||
|  | d9edb9675f | ||
|  | be6fce5a89 | ||
|  | 12afeb30ae | ||
|  | 23df406ff0 | ||
|  | c9ecef4fc3 | ||
|  | 62f0a867a8 | ||
|  | f68b8d82e0 | ||
|  | 6b7cb13e9a | ||
|  | 613af6013a | ||
|  | 0db56a781e | ||
|  | fe7674b184 | ||
|  | 44a6fe7310 | ||
|  | 46690f0c35 | ||
|  | cfc4e345cc | ||
|  | c68278d824 | ||
|  | 09600a71cd | ||
|  | d66ba70f5e | ||
|  | e7c4120d24 | ||
|  | 1212e534a8 | ||
|  | 899d0f1e42 | ||
|  | dde4ed3754 | ||
|  | b596e02752 | ||
|  | d5afe696da | ||
|  | 976be66dee | ||
|  | 98c8a6387a | ||
|  | be1b636e30 | ||
|  | 8bae0b81aa | ||
|  | 7ee19e1306 | ||
|  | 626d0dfa93 | ||
|  | 8453c616a5 | ||
|  | 56bc2944d0 | ||
|  | b2cf701e30 | ||
|  | 9a3b29acb7 | ||
|  | 85b217f167 | ||
|  | a7700d6c22 | ||
|  | 1e274518dd | ||
|  | f4f8927c79 | ||
|  | 60b7890f16 | ||
|  | 4d46290ef6 | ||
|  | 00f7e2cfc3 | ||
|  | e742708261 | ||
|  | 8c9de31c5c | ||
|  | 2bf992f0ac | ||
|  | 52a01bcc11 | ||
|  | f250e03c40 | ||
|  | 75acbfb042 | ||
|  | 740fd6f5d9 | ||
|  | c58306cd49 | ||
|  | 985696631c | ||
|  | d8a3d7f920 | ||
|  | b6b96f0eee | ||
|  | 3f037ef3cc | ||
|  | 5c2d3fb3da | ||
|  | 84d38ea878 | ||
|  | 6226aa0b23 | ||
|  | 72af35834b | ||
|  | 3019e3817f | ||
|  | da9e90faf0 | ||
|  | e737395c2b | ||
|  | 5a33167594 | ||
|  | dfb7e50948 | ||
|  | b43c9f075c | ||
|  | f42ce6adb5 | ||
|  | bf533bbdbb | ||
|  | 9328729c4c | ||
|  | 2e23a044ca | ||
|  | 691a3a1e72 | ||
|  | fc40f9634b | ||
|  | 4969441f21 | ||
|  | d04d50794e | ||
|  | 5e1fbe34a9 | ||
|  | 2b75829a0c | ||
|  | 3b3fd0a3a2 | ||
|  | 1e4b61008a | ||
|  | ffb71e9fd5 | ||
|  | c1aeb4bde6 | ||
|  | 66bca5cd81 | ||
|  | b68df3a067 | ||
|  | 066f3bb646 | ||
|  | 661c334928 | ||
|  | a1895d4157 | ||
|  | 1e7efe026a | ||
|  | 02e7da979a | ||
|  | bd2839110b | ||
|  | 1bcb2697e7 | ||
|  | fdb9a664f5 | ||
|  | 8099c334c7 | ||
|  | 344d28ab78 | ||
|  | 5e41168305 | ||
|  | dd97669cdd | ||
|  | af75581659 | ||
|  | 3c08f5b86a | ||
|  | 7809cad6cb | ||
|  | 3e59029966 | ||
|  | 24249bcb4d | ||
|  | 543011c3de | ||
|  | 4d9f2586d9 | ||
|  | 7f94ebe362 | ||
|  | c9bf1eda54 | ||
|  | 2cd4d9004c | ||
|  | 35cd0319d4 | ||
|  | 899030e966 | ||
|  | 15e3944d23 | ||
|  | f1fbaedb0f | ||
|  | cf04062a19 | ||
|  | 2e922bf7db | ||
|  | 741a731ecb | ||
|  | 91bff1976c | ||
|  | fad500042a | ||
|  | bdb2a01385 | ||
|  | f372cd2d13 | ||
|  | a435da910f | ||
|  | f1d96d9673 | ||
|  | 45226ee1f6 | ||
|  | 03b8d29740 | ||
|  | 80a4af249f | ||
|  | 900d444946 | ||
|  | 7ca9393d2d | ||
|  | b22d7bb310 | ||
|  | c742cdfe5c | ||
|  | 2d3fe02cd7 | ||
|  | 7d61cb6bac | ||
|  | a804433a7a | ||
|  | 11082320c2 | ||
|  | 9f9797b123 | ||
|  | 05d34616b7 | ||
|  | c7f474ada1 | ||
|  | c7328a63d0 | ||
|  | db818794d5 | ||
|  | b4b34e4890 | ||
|  | eec016380d | ||
|  | dcab272be0 | ||
|  | 418d033a5c | ||
|  | e7a7713b80 | ||
|  | 52a580d845 | ||
|  | ea42a0b5f5 | ||
|  | a0b63da9a6 | ||
|  | 8d9932fc42 | ||
|  | 54be45bedc | ||
|  | 3c9d2a562b | ||
|  | 654bd5175c | ||
|  | 9db660cd3f | ||
|  | 9aeadff9bd | ||
|  | cd631b789b | ||
|  | 4d98408aaf | ||
|  | 490aafba4e | ||
|  | 3cd31d49bb | ||
|  | 6dd78b8d35 | ||
|  | bd51c34098 | ||
|  | 0e758fadee | ||
|  | a67659ff8e | ||
|  | d1203f90da | ||
|  | c5f6ebee18 | ||
|  | 41cc5234c4 | ||
|  | c2d3e5f052 | ||
|  | f944b95e32 | ||
|  | 0a5b919cd9 | ||
|  | b5f85c11fe | ||
|  | 5d44b5e913 | ||
|  | dd1961d86c | ||
|  | f3539bf448 | ||
|  | d831e559f0 | ||
|  | cc079660f3 | ||
|  | 4460dac697 | ||
|  | 31190f921c | ||
|  | 22515d8dce | ||
|  | a099d970a4 | ||
|  | 95bb2c5504 | ||
|  | 0b1262cc4d | ||
|  | f9244f6f7e | ||
|  | 9dd4ea1584 | ||
|  | 9d085cdb61 | ||
|  | f00a2dbc59 | ||
|  | 20862d47ab | ||
|  | cfa1bf36de | ||
|  | c362b33b5a | ||
|  | 222a151eff | ||
|  | d6115cff25 | ||
|  | 6459522617 | ||
|  | 16e1f0eea1 | ||
|  | 0564ac1530 | ||
|  | b896f82282 | ||
|  | d737d419d9 | ||
|  | 0de2b6983b | ||
|  | 25628c34ee | ||
|  | 54fdccd397 | ||
|  | 27af4a988d | ||
|  | fddad131a2 | ||
|  | 4d493eeebd | ||
|  | 14c1495a1a | ||
|  | 49c029ddb3 | ||
|  | ddbe142c4c | ||
|  | 4710b40e45 | ||
|  | be0b296769 | ||
|  | 0a0ee67740 | ||
|  | 943d648225 | ||
|  | 6d835f5cc1 | ||
|  | a59cd67acf | ||
|  | bbc06be091 | ||
|  | d303e9f347 | ||
|  | 85ee923d89 | ||
|  | fe6ba20ff5 | ||
|  | 18acf50b12 | ||
|  | 509fabb61c | ||
|  | cc3378b4cd | ||
|  | 8d3ccf333d | ||
|  | 520919b165 | ||
|  | 600b86dd31 | ||
|  | 9c3fdd2584 | ||
|  | 73974cd90f | ||
|  | 8a60b3b402 | ||
|  | 59ed5ae6b7 | ||
|  | c687385974 | ||
|  | 2f72e15ea7 | ||
|  | 7ea99baeb2 | ||
|  | 14f3d20772 | ||
|  | 72f51df25f | ||
|  | a94b58e304 | ||
|  | d327fabf9c | ||
|  | 9e02888c74 | ||
|  | 98c9a847f3 | ||
|  | a159f4c9d6 | ||
|  | b197731ed2 | ||
|  | 028f54fdf0 | ||
|  | de62a0f8ed | ||
|  | a0fcc50a5f | ||
|  | 4f186e843c | ||
|  | df64c20587 | ||
|  | 310c18707b | ||
|  | 422a4a5578 | ||
|  | a995b2e1ae | ||
|  | 90ad681a9e | ||
|  | 5fd359a64f | ||
|  | 1bff790628 | ||
|  | 0010ca3e03 | ||
|  | 9edb5dae88 | ||
|  | 85b49096dc | ||
|  | a7eaa10220 | ||
|  | 5a46ce55b6 | ||
|  | dbebbecab1 | ||
|  | c7593e66bf | ||
|  | d52dc69279 | ||
|  | 1c65fa212d | ||
|  | be88eb00f8 | ||
|  | 65c60f5386 | ||
|  | 83a043e639 | ||
|  | 8175192f60 | ||
|  | 7d2c975d73 | ||
|  | e5153737d8 | ||
|  | 88766a02c7 | ||
|  | 8162394797 | ||
|  | fd001186dd | ||
|  | 128fef8838 | ||
|  | 1e25a0654a | ||
|  | 82b0ff6008 | ||
|  | ca7c3630f9 | ||
|  | 260bb8218f | ||
|  | a691de7d55 | ||
|  | 5674c484e2 | ||
|  | 9286dc284c | ||
|  | 624b71bd39 | ||
|  | b7ea605a3b | ||
|  | 489a787de8 | ||
|  | 84150036ed | ||
|  | 619123720c | ||
|  | cc98ff9fe6 | ||
|  | 39d159f38c | ||
|  | ca8eb90cec | ||
|  | f8e3e28d85 | ||
|  | 4d868489bd | ||
|  | b06f09f6af | ||
|  | bf00f5f945 | ||
|  | 6ceb6cc301 | ||
|  | 00a6afaa8e | 
| @@ -29,6 +29,16 @@ jobs: | ||||
|                   key: repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo | ||||
|             - save_cache: | ||||
|                   key: python-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/python-contract-wrappers/generated | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/packages/python-contract-wrappers/generated | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/packages/abi-gen/test-cli/output | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/packages/abi-gen-wrappers/generated_docs | ||||
|     build-website: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
| @@ -47,17 +57,7 @@ jobs: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-multisig | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-utils | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-exchange-libs | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-erc20 | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-erc721 | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-erc1155 | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-extensions | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-asset-proxy | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-exchange | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-exchange-forwarder | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-coordinator | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-extensions @0x/contracts-asset-proxy @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-coordinator @0x/contracts-dev-utils | ||||
|     test-contracts-geth: | ||||
|         docker: | ||||
|             - image: circleci/node:9-browsers | ||||
| @@ -69,17 +69,7 @@ jobs: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             # HACK(albrow): we need to sleep 10 seconds to ensure the devnet is | ||||
|             # initialized | ||||
|             - run: sleep 10 && TEST_PROVIDER=geth yarn wsrun test @0x/contracts-multisig | ||||
|             - run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-utils | ||||
|             - run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-exchange-libs | ||||
|             - run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-erc20 | ||||
|             - run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-erc721 | ||||
|             - run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-erc1155 | ||||
|             - run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-extensions | ||||
|             - run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-asset-proxy | ||||
|             - run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-exchange | ||||
|             - run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-exchange-forwarder | ||||
|             - run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-coordinator | ||||
|             - run: sleep 10 && TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-extensions @0x/contracts-asset-proxy @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-coordinator @0x/contracts-dev-utils | ||||
|     test-publish: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
| @@ -100,20 +90,6 @@ jobs: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: yarn test:generate_docs:circleci | ||||
|     test-pipeline: | ||||
|         docker: | ||||
|             - image: circleci/node:9 | ||||
|             - image: postgres:11-alpine | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: ZEROEX_DATA_PIPELINE_TEST_DB_URL='postgresql://postgres@localhost/postgres' yarn wsrun test:circleci @0x/pipeline | ||||
|             - save_cache: | ||||
|                   key: coverage-pipeline-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/pipeline/coverage/lcov.info | ||||
|     test-rest: | ||||
|         docker: | ||||
|             - image: circleci/node:9-browsers | ||||
| @@ -124,6 +100,7 @@ jobs: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-test-utils | ||||
|             - run: yarn wsrun test:circleci @0x/abi-gen | ||||
|             - run: yarn wsrun test:circleci @0x/asset-buyer | ||||
|             - run: yarn wsrun test:circleci @0x/contract-artifacts | ||||
|             - run: yarn wsrun test:circleci @0x/assert | ||||
|             - run: yarn wsrun test:circleci @0x/base-contract | ||||
| @@ -131,7 +108,6 @@ jobs: | ||||
|             - run: yarn wsrun test:circleci @0x/contract-wrappers | ||||
|             - run: yarn wsrun test:circleci @0x/dev-utils | ||||
|             - run: yarn wsrun test:circleci @0x/json-schemas | ||||
|             - run: yarn wsrun test:circleci @0x/metacoin | ||||
|             - run: yarn wsrun test:circleci @0x/order-utils | ||||
|             - run: yarn wsrun test:circleci @0x/order-watcher | ||||
|             - run: yarn wsrun test:circleci @0x/sol-compiler | ||||
| @@ -149,6 +125,10 @@ jobs: | ||||
|                   key: coverage-assert-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/assert/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-asset-buyer-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/asset-buyer/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
| @@ -169,10 +149,6 @@ jobs: | ||||
|                   key: coverage-json-schemas-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/json-schemas/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/metacoin/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-order-utils-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
| @@ -206,32 +182,37 @@ jobs: | ||||
|         docker: | ||||
|             - image: circleci/python | ||||
|             - image: 0xorg/ganache-cli:2.2.2 | ||||
|             - image: 0xorg/launch-kit-ci | ||||
|             - image: 0xorg/launch-kit-backend:74bcc39 | ||||
|               environment: | ||||
|                   RPC_URL: http://localhost:8545 | ||||
|                   NETWORK_ID: 50 | ||||
|                   WHITELIST_ALL_TOKENS: True | ||||
|               command: bash -c "until curl -sfd'{\"method\":\"net_listening\"}' http://localhost:8545 | grep true; do continue; done; forever ts/lib/index.js" | ||||
|               command: | | ||||
|                   sh -c "until printf 'POST /\r\nContent-Length: 26\r\n\r\n{\"method\":\"net_listening\"}' | nc localhost 8545 | grep true; do continue; done; node_modules/.bin/forever ts/lib/index.js" | ||||
|         steps: | ||||
|             - checkout | ||||
|             - run: sudo chown -R circleci:circleci /usr/local/bin | ||||
|             - run: sudo chown -R circleci:circleci /usr/local/lib/python3.7 | ||||
|             - restore_cache: | ||||
|                   key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   key: python-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: | ||||
|                   command: | | ||||
|                       cd python-packages | ||||
|                       python -m ensurepip | ||||
|                       ./pre_install | ||||
|                       ./install | ||||
|             - save_cache: | ||||
|                   key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - '/usr/local/bin' | ||||
|                       - '/usr/local/lib/python3.7/site-packages' | ||||
|             - run: | ||||
|                   command: | | ||||
|                       cd python-packages | ||||
|                       ./cmd_pkgs_in_dep_order.py coverage run setup.py test | ||||
|                       ./parallel_without_sra_client coverage run setup.py test | ||||
|                       ./build_docs | ||||
|             - save_cache: | ||||
|                   key: coverage-python-contract-addresses-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
| @@ -256,6 +237,24 @@ jobs: | ||||
|                   key: coverage-python-sra-client-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/python-packages/sra_client/.coverage | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_token/__init__.py | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/__init__.py | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/python-packages/contract_addresses/build | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/python-packages/contract_artifacts/build | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/python-packages/contract_wrappers/build | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/python-packages/json_schemas/build | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/python-packages/middlewares/build | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/python-packages/order_utils/build | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/python-packages/sra_client/build | ||||
|     test-rest-python: | ||||
|         working_directory: ~/repo | ||||
|         docker: | ||||
| @@ -265,14 +264,14 @@ jobs: | ||||
|             - run: sudo chown -R circleci:circleci /usr/local/bin | ||||
|             - run: sudo chown -R circleci:circleci /usr/local/lib/python3.7 | ||||
|             - restore_cache: | ||||
|                   key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: | ||||
|                   command: | | ||||
|                       cd python-packages/order_utils | ||||
|                       python -m ensurepip | ||||
|                       python -m pip install . | ||||
|             - save_cache: | ||||
|                   key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - '/usr/local/bin' | ||||
|                       - '/usr/local/lib/python3.7/site-packages' | ||||
| @@ -293,11 +292,14 @@ jobs: | ||||
|             - run: sudo chown -R circleci:circleci /usr/local/bin | ||||
|             - run: sudo chown -R circleci:circleci /usr/local/lib/python3.7 | ||||
|             - restore_cache: | ||||
|                   key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   key: python-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: | ||||
|                   command: | | ||||
|                       python -m ensurepip | ||||
|                       cd python-packages | ||||
|                       ./pre_install | ||||
|                       ./install | ||||
|                       ./lint | ||||
|     static-tests: | ||||
| @@ -327,6 +329,9 @@ jobs: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-assert-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-asset-buyer-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }} | ||||
| @@ -342,9 +347,6 @@ jobs: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-json-schemas-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-order-utils-{{ .Environment.CIRCLE_SHA1 }} | ||||
| @@ -404,9 +406,6 @@ workflows: | ||||
|             # - test-contracts-geth: | ||||
|             #       requires: | ||||
|             #           - build | ||||
|             - test-pipeline: | ||||
|                   requires: | ||||
|                       - build | ||||
|             - test-rest: | ||||
|                   requires: | ||||
|                       - build | ||||
| @@ -426,6 +425,8 @@ workflows: | ||||
|             - static-tests-python: | ||||
|                   requires: | ||||
|                       - test-python | ||||
|             - test-python | ||||
|             - test-python: | ||||
|                   requires: | ||||
|                       - build | ||||
|             # skip python tox run for now, as we don't yet have multiple test environments to support. | ||||
|             #- test-rest-python | ||||
|   | ||||
							
								
								
									
										7
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							| @@ -1,7 +1,8 @@ | ||||
| *.sol linguist-language=Solidity | ||||
|  | ||||
| # Automatically collapse generated files in GitHub. | ||||
| *.svg linguist-generated | ||||
| packages/contract-artifacts/artifacts/*json linguist-generated | ||||
| packages/abi-gen-wrappers/wrappers/*.ts liguist-generated | ||||
| *.svg linguist-generated=true | ||||
| packages/contract-artifacts/artifacts/*json linguist-generated=true | ||||
| packages/abi-gen-wrappers/src/generated-wrappers/*.ts linguist-generated=true | ||||
| packages/contract-wrappers/src/generated-wrappers/*.ts linguist-generated=true | ||||
|  | ||||
|   | ||||
							
								
								
									
										77
									
								
								.github/autolabeler.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								.github/autolabeler.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,43 +1,40 @@ | ||||
| python: ['python-packages'] | ||||
| contracts: ['contracts'] | ||||
| sol-doc: ['packages/sol-doc'] | ||||
| sol-resolver: ['packages/sol-resolver'] | ||||
| contracts-gen: ['packages/contracts-gen'] | ||||
| sra-spec: ['packages/sra-spec'] | ||||
| subproviders: ['packages/subproviders'] | ||||
| contract-addresses: ['packages/contract-addresses'] | ||||
| migrations: ['packages/migrations'] | ||||
| web3-wrapper: ['packages/web3-wrapper'] | ||||
| sol-compiler: ['packages/sol-compiler'] | ||||
| types: ['packages/types'] | ||||
| instant: ['packages/instant'] | ||||
| abi-gen-templates: ['packages/abi-gen-templates'] | ||||
| abi-gen: ['packages/abi-gen'] | ||||
| website: ['packages/website'] | ||||
| sol-coverage: ['packages/sol-coverage'] | ||||
| sol-profiler: ['packages/sol-profiler'] | ||||
| sol-trace: ['packages/sol-trace'] | ||||
| sol-tracing-utils: ['packages/sol-tracing-utils'] | ||||
| utils: ['packages/utils'] | ||||
| tslint-config: ['packages/tslint-config'] | ||||
| asset-buyer: ['packages/asset-buyer'] | ||||
| order-watcher: ['packages/order-watcher'] | ||||
| react-docs: ['packages/react-docs'] | ||||
| order-utils: ['packages/order-utils'] | ||||
| react-shared: ['packages/react-shared'] | ||||
| assert: ['packages/assert'] | ||||
| base-contract: ['packages/base-contract'] | ||||
| typescript-typings: ['packages/typescript-typings'] | ||||
| @0x/sol-doc: ['packages/sol-doc'] | ||||
| @0x/sol-resolver: ['packages/sol-resolver'] | ||||
| @0x/contracts-gen: ['packages/contracts-gen'] | ||||
| @0x/sra-spec: ['packages/sra-spec'] | ||||
| @0x/subproviders: ['packages/subproviders'] | ||||
| @0x/contract-addresses: ['packages/contract-addresses'] | ||||
| @0x/migrations: ['packages/migrations'] | ||||
| @0x/web3-wrapper: ['packages/web3-wrapper'] | ||||
| @0x/sol-compiler: ['packages/sol-compiler'] | ||||
| @0x/types: ['packages/types'] | ||||
| @0x/instant: ['packages/instant'] | ||||
| @0x/abi-gen-templates: ['packages/abi-gen-templates'] | ||||
| @0x/abi-gen: ['packages/abi-gen'] | ||||
| @0x/website: ['packages/website'] | ||||
| @0x/sol-coverage: ['packages/sol-coverage'] | ||||
| @0x/sol-profiler: ['packages/sol-profiler'] | ||||
| @0x/sol-trace: ['packages/sol-trace'] | ||||
| @0x/sol-tracing-utils: ['packages/sol-tracing-utils'] | ||||
| @0x/utils: ['packages/utils'] | ||||
| @0x/tslint-config: ['packages/tslint-config'] | ||||
| @0x/asset-buyer: ['packages/asset-buyer'] | ||||
| @0x/order-watcher: ['packages/order-watcher'] | ||||
| @0x/order-utils: ['packages/order-utils'] | ||||
| @0x/assert: ['packages/assert'] | ||||
| @0x/base-contract: ['packages/base-contract'] | ||||
| @0x/typescript-typings: ['packages/typescript-typings'] | ||||
| 0x.js: ['packages/0x.js'] | ||||
| abi-gen-wrappers: ['packages/abi-gen-wrappers'] | ||||
| metacoin: ['packages/metacoin'] | ||||
| contract-artifacts: ['packages/contract-artifacts'] | ||||
| dev-utils: ['packages/dev-utils'] | ||||
| contract-wrappers: ['packages/contract-wrappers'] | ||||
| json-schemas: ['packages/json-schemas'] | ||||
| ethereum-types: ['ethereum-types'] | ||||
| connect: ['packages/connect'] | ||||
| fill-scenarios: ['packages/fill-scenarios'] | ||||
| dev-tools-pages: ['packages/dev-tools-pages'] | ||||
| testnet-faucets: ['packages/testnet-faucets'] | ||||
| monorepo-scripts: ['packages/monorepo-scripts'] | ||||
| @0x/abi-gen-wrappers: ['packages/abi-gen-wrappers'] | ||||
| @0x/contract-artifacts: ['packages/contract-artifacts'] | ||||
| @0x/dev-utils: ['packages/dev-utils'] | ||||
| @0x/contract-wrappers: ['packages/contract-wrappers'] | ||||
| @0x/json-schemas: ['packages/json-schemas'] | ||||
| @0x/ethereum-types: ['ethereum-types'] | ||||
| @0x/connect: ['packages/connect'] | ||||
| @0x/fill-scenarios: ['packages/fill-scenarios'] | ||||
| @0x/dev-tools-pages: ['packages/dev-tools-pages'] | ||||
| @0x/testnet-faucets: ['packages/testnet-faucets'] | ||||
| @0x/monorepo-scripts: ['packages/monorepo-scripts'] | ||||
|   | ||||
							
								
								
									
										35
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -77,7 +77,6 @@ TODO.md | ||||
|  | ||||
| packages/website/public/bundle* | ||||
| packages/dev-tools-pages/public/bundle* | ||||
| packages/react-docs/example/public/bundle* | ||||
|  | ||||
| # server cli | ||||
| packages/testnet-faucets/server/ | ||||
| @@ -94,11 +93,13 @@ contracts/erc721/generated-artifacts/ | ||||
| contracts/erc1155/generated-artifacts/ | ||||
| contracts/extensions/generated-artifacts/ | ||||
| contracts/exchange-forwarder/generated-artifacts/ | ||||
| contracts/dev-utils/generated-artifacts/ | ||||
| packages/sol-tracing-utils/test/fixtures/artifacts/ | ||||
| packages/metacoin/artifacts/ | ||||
| python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/ | ||||
|  | ||||
| # generated contract wrappers | ||||
| packages/abi-gen-wrappers/wrappers | ||||
| packages/abi-gen-wrappers/src/generated-wrappers/ | ||||
| packages/python-contract-wrappers/generated/ | ||||
| contracts/coordinator/generated-wrappers/ | ||||
| contracts/exchange/generated-wrappers/ | ||||
| contracts/asset-proxy/generated-wrappers/ | ||||
| @@ -110,7 +111,30 @@ contracts/erc721/generated-wrappers/ | ||||
| contracts/erc1155/generated-wrappers/ | ||||
| contracts/extensions/generated-wrappers/ | ||||
| contracts/exchange-forwarder/generated-wrappers/ | ||||
| packages/metacoin/src/contract_wrappers | ||||
| contracts/dev-utils/generated-wrappers/ | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_token/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/asset_proxy_owner/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/coordinator/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/coordinator_registry/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dummy_erc20_token/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dummy_erc721_token/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dutch_auction/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_proxy/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_proxy/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_token/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/eth_balance_checker/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/forwarder/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_asset_proxy/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_validator/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_wallet/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/multi_asset_proxy/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_validator/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/weth9/__init__.py | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/zrx_token/__init__.py | ||||
|  | ||||
| # cli test output | ||||
| packages/abi-gen/test-cli/output | ||||
|  | ||||
| # solc-bin in sol-compiler | ||||
| packages/sol-compiler/solc_bin/ | ||||
| @@ -127,3 +151,6 @@ python-packages/*/dist | ||||
| __pycache__ | ||||
| python-packages/*/src/*.egg-info | ||||
| python-packages/*/.coverage | ||||
|  | ||||
| # python keeps package-local copies of json schemas | ||||
| python-packages/json_schemas/src/zero_ex/json_schemas/schemas | ||||
|   | ||||
| @@ -22,13 +22,11 @@ lib | ||||
| /contracts/extensions/generated-artifacts | ||||
| /contracts/exchange-forwarder/generated-wrappers | ||||
| /contracts/exchange-forwarder/generated-artifacts | ||||
| /packages/abi-gen-wrappers/src/generated-wrappers | ||||
| /packages/contract-artifacts/artifacts | ||||
| /python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts | ||||
| /contracts/dev-utils/generated-wrappers | ||||
| /contracts/dev-utils/generated-artifacts | ||||
| /packages/abi-gen/test-cli/output | ||||
| /packages/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/ | ||||
| /packages/dev-tools-pages/ts/**/data.json | ||||
| package.json | ||||
| @@ -37,3 +35,6 @@ packages/sol-coverage/test/fixtures/artifacts | ||||
| .pytest_cache | ||||
| .mypy_cache | ||||
| .tox | ||||
| packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json | ||||
| packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json | ||||
| packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json | ||||
|   | ||||
| @@ -11,18 +11,18 @@ packages/website/  @BMillman19 @fragosti @fabioberger @steveklebanoff | ||||
|  | ||||
| # Dev tools & setup | ||||
| .circleci/ @LogvinovLeon | ||||
| packages/abi-gen/ @LogvinovLeon | ||||
| packages/base-contract/ @LogvinovLeon | ||||
| packages/abi-gen/ @feuGeneA | ||||
| packages/base-contract/ @xianny | ||||
| packages/connect/ @fragosti  | ||||
| packages/abi-gen-templates/ @LogvinovLeon | ||||
| packages/abi-gen-templates/ @feuGeneA @xianny | ||||
| packages/contract-addresses/ @albrow | ||||
| packages/contract-artifacts/ @albrow | ||||
| packages/dev-utils/ @LogvinovLeon @fabioberger | ||||
| packages/devnet/ @albrow | ||||
| packages/ethereum-types/ @LogvinovLeon | ||||
| packages/metacoin/ @LogvinovLeon | ||||
| packages/monorepo-scripts/ @fabioberger | ||||
| packages/order-utils/ @fabioberger @LogvinovLeon  | ||||
| packages/python-contract-wrappers/ @feuGeneA | ||||
| packages/sol-compiler/ @LogvinovLeon | ||||
| packages/sol-coverage/ @LogvinovLeon | ||||
| packages/sol-profiler/ @LogvinovLeon | ||||
| @@ -36,5 +36,4 @@ python-packages/ @feuGeneA | ||||
| packages/utils/ @hysz | ||||
|  | ||||
| # Protocol/smart contracts | ||||
| contracts/core/test/ @albrow | ||||
| contracts/ @abandeali1 @hysz | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| <!--- Before submitting please check to see if this issue was already reported --> | ||||
|  | ||||
| <!--- Provide a general summary of the issue in the Title above --> | ||||
| <!--- Prefix your issue title with the package name it relates to (e.g., `0x.js: ` or `general:`) --> | ||||
|  | ||||
| ## Expected Behavior | ||||
|  | ||||
|   | ||||
							
								
								
									
										26
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								README.md
									
									
									
									
									
								
							| @@ -50,6 +50,7 @@ These packages are all under development. See [/contracts/README.md](/contracts/ | ||||
| | [`@0x/contracts-test-utils`](/contracts/test-utils)                 | [](https://www.npmjs.com/package/@0x/contracts-test-utils)                 | Typescript/Javascript shared utilities used for testing contracts                                                                                                                                                                                     | | ||||
| | [`@0x/contracts-utils`](/contracts/utils)                           | [](https://www.npmjs.com/package/@0x/contracts-utils)                           | Generic libraries and utilities used throughout all of the contracts                                                                                                                                                                                  | | ||||
| | [`@0x/contracts-coordinator`](/contracts/coordinator)               | [](https://www.npmjs.com/package/@0x/contracts-coordinator)               | A contract that allows users to execute 0x transactions with permission from a Coordinator                                                                                                                                                            | | ||||
| | [`@0x/contracts-dev-utils`](/contracts/dev-utils)                   | [](https://www.npmjs.com/package/@0x/contracts-dev-utils)                   | A contract contains utility functions for developers (such as validating many orders using a single eth_call)                                                                                                                                         | | ||||
|  | ||||
| ### Typescript/Javascript Packages | ||||
|  | ||||
| @@ -69,6 +70,7 @@ These packages are all under development. See [/contracts/README.md](/contracts/ | ||||
| | [`@0x/sra-spec`](/packages/sra-spec)                     | [](https://www.npmjs.com/package/@0x/sra-spec)                     | OpenAPI specification for the Standard Relayer API                                                | | ||||
| | [`@0x/connect`](/packages/connect)                       | [](https://www.npmjs.com/package/@0x/connect)                       | An HTTP/WS client for interacting with the Standard Relayer API                                   | | ||||
| | [`@0x/asset-buyer`](/packages/asset-buyer)               | [](https://www.npmjs.com/package/@0x/asset-buyer)               | Convenience package for discovering and buying assets with Ether                                  | | ||||
| | [`@0x/asset-swapper`](/packages/asset-swapper)           | [](https://www.npmjs.com/package/@0x/asset-swapper)           | Convenience package for discovering and performing swaps for any ERC20 Assets                     | | ||||
|  | ||||
| #### Ethereum tooling | ||||
|  | ||||
| @@ -85,19 +87,17 @@ These packages are all under development. See [/contracts/README.md](/contracts/ | ||||
|  | ||||
| #### Utilities | ||||
|  | ||||
| | Package                                                  | Version                                                                                                                 | Description                                                                  | | ||||
| | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | | ||||
| | [`@0x/abi-gen`](/packages/abi-gen)                       | [](https://www.npmjs.com/package/@0x/abi-gen)                       | Tool to generate TS wrappers from smart contract ABIs                        | | ||||
| | [`@0x/tslint-config`](/packages/tslint-config)           | [](https://www.npmjs.com/package/@0x/tslint-config)           | Custom TSLint rules used by the 0x core team                                 | | ||||
| | [`@0x/types`](/packages/types)                           | [](https://www.npmjs.com/package/@0x/types)                           | Shared type declarations                                                     | | ||||
| | [`@0x/typescript-typings`](/packages/typescript-typings) | [](https://www.npmjs.com/package/@0x/typescript-typings) | Repository of types for external packages                                    | | ||||
| | [`@0x/utils`](/packages/utils)                           | [](https://www.npmjs.com/package/@0x/utils)                           | Shared utilities                                                             | | ||||
| | [`@0x/react-docs`](/packages/react-docs)                 | [](https://www.npmjs.com/package/@0x/react-docs)                 | React documentation component for rendering TypeDoc & sol-doc generated JSON | | ||||
| | [`@0x/react-shared`](/packages/react-shared)             | [](https://www.npmjs.com/package/@0x/react-shared)             | 0x shared react components                                                   | | ||||
| | [`@0x/assert`](/packages/assert)                         | [](https://www.npmjs.com/package/@0x/assert)                         | Type and schema assertions used by our packages                              | | ||||
| | [`@0x/base-contract`](/packages/base-contract)           | [](https://www.npmjs.com/package/@0x/base-contract)           | BaseContract used by auto-generated `abi-gen` wrapper contracts              | | ||||
| | [`@0x/dev-utils`](/packages/dev-utils)                   | [](https://www.npmjs.com/package/@0x/dev-utils)                   | Dev utils to be shared across 0x packages                                    | | ||||
| | [`@0x/fill-scenarios`](/packages/fill-scenarios)         | [](https://www.npmjs.com/package/@0x/fill-scenarios)         | 0x order fill scenario generator                                             | | ||||
| | Package                                                  | Version                                                                                                                 | Description                                                     | | ||||
| | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | | ||||
| | [`@0x/abi-gen`](/packages/abi-gen)                       | [](https://www.npmjs.com/package/@0x/abi-gen)                       | Tool to generate TS wrappers from smart contract ABIs           | | ||||
| | [`@0x/tslint-config`](/packages/tslint-config)           | [](https://www.npmjs.com/package/@0x/tslint-config)           | Custom TSLint rules used by the 0x core team                    | | ||||
| | [`@0x/types`](/packages/types)                           | [](https://www.npmjs.com/package/@0x/types)                           | Shared type declarations                                        | | ||||
| | [`@0x/typescript-typings`](/packages/typescript-typings) | [](https://www.npmjs.com/package/@0x/typescript-typings) | Repository of types for external packages                       | | ||||
| | [`@0x/utils`](/packages/utils)                           | [](https://www.npmjs.com/package/@0x/utils)                           | Shared utilities                                                | | ||||
| | [`@0x/assert`](/packages/assert)                         | [](https://www.npmjs.com/package/@0x/assert)                         | Type and schema assertions used by our packages                 | | ||||
| | [`@0x/base-contract`](/packages/base-contract)           | [](https://www.npmjs.com/package/@0x/base-contract)           | BaseContract used by auto-generated `abi-gen` wrapper contracts | | ||||
| | [`@0x/dev-utils`](/packages/dev-utils)                   | [](https://www.npmjs.com/package/@0x/dev-utils)                   | Dev utils to be shared across 0x packages                       | | ||||
| | [`@0x/fill-scenarios`](/packages/fill-scenarios)         | [](https://www.npmjs.com/package/@0x/fill-scenarios)         | 0x order fill scenario generator                                | | ||||
|  | ||||
| #### Private Packages | ||||
|  | ||||
|   | ||||
| @@ -10,3 +10,7 @@ | ||||
| | Forwarder       | [`@0x/contracts-exchange-forwarder`](/contracts/exchange-forwarder) | [v1.0.1](https://www.npmjs.com/package/@0x/contracts-exchange-forwarder/v/1.0.1) | [@0x/contracts-exchange-forwarder@1.0.1](https://github.com/0xProject/0x-monorepo/releases/tag/@0x/contracts-exchange-forwarder@1.0.1) | | ||||
| | MultiAssetProxy | [`@0x/contracts-asset-proxy`](/contracts/asset-proxy)               | [v1.0.1](https://www.npmjs.com/package/@0x/contracts-asset-proxy/v/1.0.1)        | [@0x/contracts-asset-proxy@1.0.1](https://github.com/0xProject/0x-monorepo/releases/tag/@0x/contracts-asset-proxy@1.0.1)               | | ||||
| | ZRXToken        | [`@0x/contracts-erc20`](/contracts/erc20)                           | [v1.0.1](https://www.npmjs.com/package/@0x/contracts-erc20/v/1.0.1)              | [@0x/contracts-erc20@1.0.1](https://github.com/0xProject/0x-monorepo/releases/tag/@0x/contracts-erc20@1.0.1)                           | | ||||
|  | ||||
| #### Development | ||||
|  | ||||
| Building solidity files will update the contract artifact in `{package-name}/generated-artifacts/{contract}.json`, but does not automatically update the `abi-gen-wrappers` package, which are generated from the artifact JSON. To ensure consistency, clean and rebuild `abi-gen-wrappers` after any changes to the artifact JSON. | ||||
|   | ||||
| @@ -1,4 +1,105 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1565296576, | ||||
|         "version": "2.2.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.2.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies.", | ||||
|                 "pr": 1995 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1564607468 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563957393, | ||||
|         "version": "2.2.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563193019, | ||||
|         "version": "2.2.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563047529, | ||||
|         "version": "2.2.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.2.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add `LibAssetProxyIds` contract", | ||||
|                 "pr": 1835 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Updated ERC1155 Asset Proxy. Less optimization. More explicit handling of edge cases.", | ||||
|                 "pr": 1852 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Implement StaticCallProxy", | ||||
|                 "pr": 1863 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1563006338 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1558712885, | ||||
|         "version": "2.1.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557961111, | ||||
|         "version": "2.1.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557799313, | ||||
|         "version": "2.1.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.1.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Update tests to use contract-built-in `awaitTransactionSuccessAsync`", | ||||
|                 "pr": 1797 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1557507213 | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.1.1", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,48 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v2.2.5 - _August 8, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.4 - _July 31, 2019_ | ||||
|  | ||||
|     * Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies. (#1995) | ||||
|  | ||||
| ## v2.2.3 - _July 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.2 - _July 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.1 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.0 - _July 13, 2019_ | ||||
|  | ||||
|     * Add `LibAssetProxyIds` contract (#1835) | ||||
|     * Updated ERC1155 Asset Proxy. Less optimization. More explicit handling of edge cases. (#1852) | ||||
|     * Implement StaticCallProxy (#1863) | ||||
|  | ||||
| ## v2.1.5 - _May 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.4 - _May 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.3 - _May 14, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.2 - _May 10, 2019_ | ||||
|  | ||||
|     * Update tests to use contract-built-in `awaitTransactionSuccessAsync` (#1797) | ||||
|  | ||||
| ## v2.1.1 - _April 11, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|     "artifactsDir": "./generated-artifacts", | ||||
|     "contractsDir": "./contracts", | ||||
|     "useDockerisedSolc": true, | ||||
|     "useDockerisedSolc": false, | ||||
|     "isOfflineMode": false, | ||||
|     "compilerSettings": { | ||||
|         "evmVersion": "constantinople", | ||||
| @@ -14,6 +14,7 @@ | ||||
|             "*": { | ||||
|                 "*": [ | ||||
|                     "abi", | ||||
|                     "devdoc", | ||||
|                     "evm.bytecode.object", | ||||
|                     "evm.bytecode.sourceMap", | ||||
|                     "evm.deployedBytecode.object", | ||||
| @@ -28,8 +29,10 @@ | ||||
|         "src/ERC721Proxy.sol", | ||||
|         "src/MixinAuthorizable.sol", | ||||
|         "src/MultiAssetProxy.sol", | ||||
|         "src/StaticCallProxy.sol", | ||||
|         "src/interfaces/IAssetData.sol", | ||||
|         "src/interfaces/IAssetProxy.sol", | ||||
|         "src/interfaces/IAuthorizable.sol" | ||||
|         "src/interfaces/IAuthorizable.sol", | ||||
|         "test/TestStaticCallTarget.sol" | ||||
|     ] | ||||
| } | ||||
|   | ||||
| @@ -16,243 +16,73 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.5.5; | ||||
| pragma solidity ^0.5.9; | ||||
|  | ||||
| import "@0x/contracts-utils/contracts/src/LibBytes.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/SafeMath.sol"; | ||||
| import "@0x/contracts-erc1155/contracts/src/interfaces/IERC1155.sol"; | ||||
| import "./MixinAuthorizable.sol"; | ||||
| import "./interfaces/IAssetProxy.sol"; | ||||
|  | ||||
|  | ||||
| contract ERC1155Proxy is | ||||
|     MixinAuthorizable | ||||
|     MixinAuthorizable, | ||||
|     SafeMath, | ||||
|     IAssetProxy | ||||
| { | ||||
|     using LibBytes for bytes; | ||||
|  | ||||
|     // Id of this proxy. | ||||
|     bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC1155Assets(address,uint256[],uint256[],bytes)")); | ||||
|  | ||||
|     function ()  | ||||
|     /// @dev Transfers batch of ERC1155 assets. Either succeeds or throws. | ||||
|     /// @param assetData Byte array encoded with ERC1155 token address, array of ids, array of values, and callback data. | ||||
|     /// @param from Address to transfer assets from. | ||||
|     /// @param to Address to transfer assets to. | ||||
|     /// @param amount Amount that will be multiplied with each element of `assetData.values` to scale the | ||||
|     ///        values that will be transferred. | ||||
|     function transferFrom( | ||||
|         bytes calldata assetData, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         external | ||||
|         onlyAuthorized | ||||
|     { | ||||
|         // Input calldata to this function is encoded as follows: | ||||
|         //                      -- TABLE #1 -- | ||||
|         // | Area     | Offset (**) | Length      | Contents                        | | ||||
|         // |----------|-------------|-------------|---------------------------------| | ||||
|         // | Header   | 0           | 4           | function selector               | | ||||
|         // | Params   |             | 4 * 32      | function parameters:            | | ||||
|         // |          | 4           |             |   1. offset to assetData (*)    | | ||||
|         // |          | 36          |             |   2. from                       | | ||||
|         // |          | 68          |             |   3. to                         | | ||||
|         // |          | 100         |             |   4. amount                     | | ||||
|         // | Data     |             |             | assetData:                      | | ||||
|         // |          | 132         | 32          | assetData Length                | | ||||
|         // |          | 164         | (see below) | assetData Contents              | | ||||
|         // | ||||
|         // | ||||
|         // Asset data is encoded as follows: | ||||
|         //                      -- TABLE #2 -- | ||||
|         // | Area     | Offset      | Length  | Contents                            | | ||||
|         // |----------|-------------|---------|-------------------------------------| | ||||
|         // | Header   | 0           | 4       | assetProxyId                        | | ||||
|         // | Params   |             | 4 * 32  | function parameters:                | | ||||
|         // |          | 4           |         |   1. address of ERC1155 contract    | | ||||
|         // |          | 36          |         |   2. offset to ids (*)              | | ||||
|         // |          | 68          |         |   3. offset to values (*)           | | ||||
|         // |          | 100         |         |   4. offset to data (*)             | | ||||
|         // | Data     |             |         | ids:                                | | ||||
|         // |          | 132         | 32      |   1. ids Length                     | | ||||
|         // |          | 164         | a       |   2. ids Contents                   |  | ||||
|         // |          |             |         | values:                             | | ||||
|         // |          | 164 + a     | 32      |   1. values Length                  | | ||||
|         // |          | 196 + a     | b       |   2. values Contents                | | ||||
|         // |          |             |         | data                                | | ||||
|         // |          | 196 + a + b | 32      |   1. data Length                    | | ||||
|         // |          | 228 + a + b | c       |   2. data Contents                  | | ||||
|         // | ||||
|         // | ||||
|         // Calldata for target ERC155 asset is encoded for safeBatchTransferFrom: | ||||
|         //                      -- TABLE #3 -- | ||||
|         // | Area     | Offset (**) | Length  | Contents                            | | ||||
|         // |----------|-------------|---------|-------------------------------------| | ||||
|         // | Header   | 0           | 4       | safeBatchTransferFrom selector      | | ||||
|         // | Params   |             | 5 * 32  | function parameters:                | | ||||
|         // |          | 4           |         |   1. from address                   | | ||||
|         // |          | 36          |         |   2. to address                     | | ||||
|         // |          | 68          |         |   3. offset to ids (*)              | | ||||
|         // |          | 100         |         |   4. offset to values (*)           | | ||||
|         // |          | 132         |         |   5. offset to data (*)             | | ||||
|         // | Data     |             |         | ids:                                | | ||||
|         // |          | 164         | 32      |   1. ids Length                     | | ||||
|         // |          | 196         | a       |   2. ids Contents                   |  | ||||
|         // |          |             |         | values:                             | | ||||
|         // |          | 196 + a     | 32      |   1. values Length                  | | ||||
|         // |          | 228 + a     | b       |   2. values Contents                | | ||||
|         // |          |             |         | data                                | | ||||
|         // |          | 228 + a + b | 32      |   1. data Length                    | | ||||
|         // |          | 260 + a + b | c       |   2. data Contents                  | | ||||
|         // | ||||
|         // | ||||
|         // (*): offset is computed from start of function parameters, so offset | ||||
|         //      by an additional 4 bytes in the calldata. | ||||
|         //  | ||||
|         // (**): the `Offset` column is computed assuming no calldata compression; | ||||
|         //       offsets in the Data Area are dynamic and should be evaluated in | ||||
|         //       real-time. | ||||
|         // | ||||
|         // WARNING: The ABIv2 specification allows additional padding between | ||||
|         //          the Params and Data section. This will result in a larger | ||||
|         //          offset to assetData. | ||||
|         // | ||||
|         // Note: Table #1 and Table #2 exists in Calldata. We construct Table #3 in memory.  | ||||
|         // | ||||
|         // | ||||
|         assembly { | ||||
|             // The first 4 bytes of calldata holds the function selector | ||||
|             let selector := and(calldataload(0), 0xffffffff00000000000000000000000000000000000000000000000000000000) | ||||
|         // Decode params from `assetData` | ||||
|         // solhint-disable indent | ||||
|         ( | ||||
|             address erc1155TokenAddress, | ||||
|             uint256[] memory ids, | ||||
|             uint256[] memory values, | ||||
|             bytes memory data | ||||
|         ) = abi.decode( | ||||
|             assetData.sliceDestructive(4, assetData.length), | ||||
|             (address, uint256[], uint256[], bytes) | ||||
|         ); | ||||
|         // solhint-enable indent | ||||
|  | ||||
|             // `transferFrom` will be called with the following parameters: | ||||
|             // assetData Encoded byte array. | ||||
|             // from Address to transfer asset from. | ||||
|             // to Address to transfer asset to. | ||||
|             // amount Amount of asset to transfer. | ||||
|             // bytes4(keccak256("transferFrom(bytes,address,address,uint256)")) = 0xa85e59e4 | ||||
|             if eq(selector, 0xa85e59e400000000000000000000000000000000000000000000000000000000) { | ||||
|                  | ||||
|                 // To lookup a value in a mapping, we load from the storage location keccak256(k, p), | ||||
|                 // where k is the key left padded to 32 bytes and p is the storage slot | ||||
|                 mstore(0, caller) | ||||
|                 mstore(32, authorized_slot) | ||||
|  | ||||
|                  // Revert if authorized[msg.sender] == false | ||||
|                 if iszero(sload(keccak256(0, 64))) { | ||||
|                     // Revert with `Error("SENDER_NOT_AUTHORIZED")` | ||||
|                     mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) | ||||
|                     mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000) | ||||
|                     mstore(64, 0x0000001553454e4445525f4e4f545f415554484f52495a454400000000000000) | ||||
|                     mstore(96, 0) | ||||
|                     revert(0, 100) | ||||
|                 } | ||||
|  | ||||
|                 // Construct Table #3 in memory, starting at memory offset 0. | ||||
|                 // The algorithm below maps asset data from Table #1 and Table #2 to Table #3, while | ||||
|                 // scaling the `values` (Table #2) by `amount` (Table #1). Once Table #3 has | ||||
|                 // been constructed in memory, the destination erc1155 contract is called using this  | ||||
|                 // as its calldata. This process is divided into four steps, below. | ||||
|  | ||||
|                 ////////// STEP 1/4 ////////// | ||||
|                 // Map relevant fields from assetData (Table #2) into memory (Table #3) | ||||
|                 // The Contents column of Table #2 is the same as Table #3, | ||||
|                 // beginning from parameter 3 - `offset to ids (*)` | ||||
|                 // The offsets in these rows are offset by 32 bytes in Table #3. | ||||
|                 // Strategy: | ||||
|                 // 1. Copy the assetData into memory at offset 32 | ||||
|                 // 2. Increment by 32 the offsets to `ids`, `values`, and `data` | ||||
|  | ||||
|                 // Load offset to `assetData` | ||||
|                 let assetDataOffset := calldataload(4) | ||||
|  | ||||
|                 // Load length in bytes of `assetData`, computed by: | ||||
|                 // 4 (function selector) | ||||
|                 // + assetDataOffset | ||||
|                 let assetDataLength := calldataload(add(4, assetDataOffset)) | ||||
|  | ||||
|                 // This corresponds to the beginning of the Data Area for Table #3. | ||||
|                 // Computed by: | ||||
|                 // 4 (function selector) | ||||
|                 // + assetDataOffset | ||||
|                 // + 32 (length of assetData) | ||||
|                 calldatacopy( | ||||
|                     32,                         // aligned such that "offset to ids" is at the correct location for Table #3 | ||||
|                     add(36, assetDataOffset),   // beginning of asset data contents | ||||
|                     assetDataLength             // length of asset data | ||||
|                 ) | ||||
|  | ||||
|                 // Increment by 32 the offsets to `ids`, `values`, and `data` | ||||
|                 mstore(68, add(mload(68), 32)) | ||||
|                 mstore(100, add(mload(100), 32)) | ||||
|                 mstore(132, add(mload(132), 32)) | ||||
|  | ||||
|                 // Record the address of the destination erc1155 asset for later. | ||||
|                 let assetAddress := and( | ||||
|                     mload(36), | ||||
|                     0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff | ||||
|                 ) | ||||
|  | ||||
|                 ////////// STEP 2/4 ////////// | ||||
|                 let amount := calldataload(100) | ||||
|                 let valuesOffset := add(mload(100), 4) // add 4 for calldata offset | ||||
|                 let valuesLengthInBytes := mul( | ||||
|                     mload(valuesOffset), | ||||
|                     32 | ||||
|                 ) | ||||
|                 let valuesBegin := add(valuesOffset, 32) | ||||
|                 let valuesEnd := add(valuesBegin, valuesLengthInBytes) | ||||
|                 for { let tokenValueOffset := valuesBegin } | ||||
|                     lt(tokenValueOffset, valuesEnd) | ||||
|                     { tokenValueOffset := add(tokenValueOffset, 32) } | ||||
|                 { | ||||
|                     // Load token value and generate scaled value | ||||
|                     let tokenValue := mload(tokenValueOffset) | ||||
|                     let scaledTokenValue := mul(tokenValue, amount) | ||||
|  | ||||
|                     // Revert if `amount` != 0 and multiplication resulted in an overflow | ||||
|                     if iszero(or( | ||||
|                         iszero(amount), | ||||
|                         eq(div(scaledTokenValue, amount), tokenValue) | ||||
|                     )) { | ||||
|                         // Revert with `Error("UINT256_OVERFLOW")` | ||||
|                         mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) | ||||
|                         mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000) | ||||
|                         mstore(64, 0x0000001055494e543235365f4f564552464c4f57000000000000000000000000) | ||||
|                         mstore(96, 0) | ||||
|                         revert(0, 100) | ||||
|                     } | ||||
|  | ||||
|                     // There was no overflow, update `tokenValue` with its scaled counterpart | ||||
|                     mstore(tokenValueOffset, scaledTokenValue) | ||||
|                 } | ||||
|  | ||||
|                 ////////// STEP 3/4 ////////// | ||||
|                 // Store the safeBatchTransferFrom function selector, | ||||
|                 // and copy `from`/`to` fields from Table #1 to Table #3. | ||||
|  | ||||
|                 // The function selector is computed using: | ||||
|                 // bytes4(keccak256("safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)")) | ||||
|                 mstore(0, 0x2eb2c2d600000000000000000000000000000000000000000000000000000000) | ||||
|  | ||||
|                 // Copy `from` and `to` fields from Table #1 to Table #3 | ||||
|                 calldatacopy( | ||||
|                     4,          // aligned such that `from` and `to` are at the correct location for Table #3 | ||||
|                     36,         // beginning of `from` field from Table #1 | ||||
|                     64          // 32 bytes for `from` + 32 bytes for `to` field | ||||
|                 ) | ||||
|  | ||||
|                 ////////// STEP 4/4 ////////// | ||||
|                 // Call into the destination erc1155 contract using as calldata Table #3 (constructed in-memory above) | ||||
|                 let success := call( | ||||
|                     gas,                                    // forward all gas | ||||
|                     assetAddress,                           // call address of erc1155 asset | ||||
|                     0,                                      // don't send any ETH | ||||
|                     0,                                      // pointer to start of input | ||||
|                     add(assetDataLength, 32),               // length of input (Table #3) is 32 bytes longer than `assetData` (Table #2) | ||||
|                     0,                                      // write output over memory that won't be reused | ||||
|                     0                                       // don't copy output to memory | ||||
|                 ) | ||||
|  | ||||
|                 // Revert with reason given by AssetProxy if `transferFrom` call failed | ||||
|                 if iszero(success) { | ||||
|                     returndatacopy( | ||||
|                         0,                // copy to memory at 0 | ||||
|                         0,                // copy from return data at 0 | ||||
|                         returndatasize()  // copy all return data | ||||
|                     ) | ||||
|                     revert(0, returndatasize()) | ||||
|                 } | ||||
|                  | ||||
|                 // Return if call was successful | ||||
|                 return(0, 0) | ||||
|             } | ||||
|  | ||||
|             // Revert if undefined function is called | ||||
|             revert(0, 0) | ||||
|         // Scale values up by `amount` | ||||
|         uint256 length = values.length; | ||||
|         uint256[] memory scaledValues = new uint256[](length); | ||||
|         for (uint256 i = 0; i != length; i++) { | ||||
|             // We write the scaled values to an unused location in memory in order | ||||
|             // to avoid copying over `ids` or `data`. This is possible if they are | ||||
|             // identical to `values` and the offsets for each are pointing to the  | ||||
|             // same location in the ABI encoded calldata. | ||||
|             scaledValues[i] = safeMul(values[i], amount); | ||||
|         } | ||||
|  | ||||
|         // Execute `safeBatchTransferFrom` call | ||||
|         // Either succeeds or throws | ||||
|         IERC1155(erc1155TokenAddress).safeBatchTransferFrom( | ||||
|             from, | ||||
|             to, | ||||
|             ids, | ||||
|             scaledValues, | ||||
|             data | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Gets the proxy id associated with the proxy address. | ||||
|   | ||||
| @@ -90,7 +90,10 @@ contract MultiAssetProxy is | ||||
|                 //          offset to assetData. | ||||
|  | ||||
|                 // Load offset to `assetData` | ||||
|                 let assetDataOffset := calldataload(4) | ||||
|                 let assetDataOffset := add(calldataload(4), 4) | ||||
|  | ||||
|                 // Load length in bytes of `assetData` | ||||
|                 let assetDataLength := calldataload(assetDataOffset) | ||||
|  | ||||
|                 // Asset data itself is encoded as follows: | ||||
|                 // | ||||
| @@ -108,41 +111,62 @@ contract MultiAssetProxy is | ||||
|                 // |          | 132 + a     | b       | nestedAssetData Contents (offsets)  | | ||||
|                 // |          | 132 + a + b |         | nestedAssetData[0, ..., len]        | | ||||
|  | ||||
|                 // Assert that the length of asset data: | ||||
|                 // 1. Must be at least 68 bytes (see table above) | ||||
|                 // 2. Must be a multiple of 32 (excluding the 4-byte selector) | ||||
|                 if or(lt(assetDataLength, 68), mod(sub(assetDataLength, 4), 32)) { | ||||
|                     // Revert with `Error("INVALID_ASSET_DATA_LENGTH")` | ||||
|                     mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) | ||||
|                     mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000) | ||||
|                     mstore(64, 0x00000019494e56414c49445f41535345545f444154415f4c454e475448000000) | ||||
|                     mstore(96, 0) | ||||
|                     revert(0, 100) | ||||
|                 } | ||||
|  | ||||
|                 // End of asset data in calldata | ||||
|                 // assetDataOffset | ||||
|                 // + 32 (assetData len) | ||||
|                 let assetDataEnd := add(assetDataOffset, add(assetDataLength, 32)) | ||||
|                 if gt(assetDataEnd, calldatasize()) { | ||||
|                     // Revert with `Error("INVALID_ASSET_DATA_END")` | ||||
|                     mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) | ||||
|                     mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000) | ||||
|                     mstore(64, 0x00000016494e56414c49445f41535345545f444154415f454e44000000000000) | ||||
|                     mstore(96, 0) | ||||
|                     revert(0, 100) | ||||
|                 } | ||||
|  | ||||
|                 // In order to find the offset to `amounts`, we must add: | ||||
|                 // 4 (function selector) | ||||
|                 // + assetDataOffset | ||||
|                 // assetDataOffset | ||||
|                 // + 32 (assetData len) | ||||
|                 // + 4 (assetProxyId) | ||||
|                 let amountsOffset := calldataload(add(assetDataOffset, 40)) | ||||
|                 let amountsOffset := calldataload(add(assetDataOffset, 36)) | ||||
|  | ||||
|                 // In order to find the offset to `nestedAssetData`, we must add: | ||||
|                 // 4 (function selector) | ||||
|                 // + assetDataOffset | ||||
|                 // assetDataOffset | ||||
|                 // + 32 (assetData len) | ||||
|                 // + 4 (assetProxyId) | ||||
|                 // + 32 (amounts offset) | ||||
|                 let nestedAssetDataOffset := calldataload(add(assetDataOffset, 72)) | ||||
|                 let nestedAssetDataOffset := calldataload(add(assetDataOffset, 68)) | ||||
|  | ||||
|                 // In order to find the start of the `amounts` contents, we must add:  | ||||
|                 // 4 (function selector)  | ||||
|                 // + assetDataOffset  | ||||
|                 // assetDataOffset  | ||||
|                 // + 32 (assetData len) | ||||
|                 // + 4 (assetProxyId) | ||||
|                 // + amountsOffset | ||||
|                 // + 32 (amounts len) | ||||
|                 let amountsContentsStart := add(assetDataOffset, add(amountsOffset, 72)) | ||||
|                 let amountsContentsStart := add(assetDataOffset, add(amountsOffset, 68)) | ||||
|  | ||||
|                 // Load number of elements in `amounts` | ||||
|                 let amountsLen := calldataload(sub(amountsContentsStart, 32)) | ||||
|  | ||||
|                 // In order to find the start of the `nestedAssetData` contents, we must add:  | ||||
|                 // 4 (function selector)  | ||||
|                 // + assetDataOffset  | ||||
|                 // assetDataOffset  | ||||
|                 // + 32 (assetData len) | ||||
|                 // + 4 (assetProxyId) | ||||
|                 // + nestedAssetDataOffset | ||||
|                 // + 32 (nestedAssetData len) | ||||
|                 let nestedAssetDataContentsStart := add(assetDataOffset, add(nestedAssetDataOffset, 72)) | ||||
|                 let nestedAssetDataContentsStart := add(assetDataOffset, add(nestedAssetDataOffset, 68)) | ||||
|  | ||||
|                 // Load number of elements in `nestedAssetData` | ||||
|                 let nestedAssetDataLen := calldataload(sub(nestedAssetDataContentsStart, 32)) | ||||
| @@ -204,15 +228,20 @@ contract MultiAssetProxy is | ||||
|                     let nestedAssetDataElementOffset := calldataload(add(nestedAssetDataContentsStart, i)) | ||||
|  | ||||
|                     // In order to find the start of the `nestedAssetData[i]` contents, we must add: | ||||
|                     // 4 (function selector)  | ||||
|                     // + assetDataOffset  | ||||
|                     // assetDataOffset  | ||||
|                     // + 32 (assetData len) | ||||
|                     // + 4 (assetProxyId) | ||||
|                     // + nestedAssetDataOffset | ||||
|                     // + 32 (nestedAssetData len) | ||||
|                     // + nestedAssetDataElementOffset | ||||
|                     // + 32 (nestedAssetDataElement len) | ||||
|                     let nestedAssetDataElementContentsStart := add(assetDataOffset, add(nestedAssetDataOffset, add(nestedAssetDataElementOffset, 104))) | ||||
|                     let nestedAssetDataElementContentsStart := add( | ||||
|                         assetDataOffset, | ||||
|                         add( | ||||
|                             nestedAssetDataOffset, | ||||
|                             add(nestedAssetDataElementOffset, 100) | ||||
|                         ) | ||||
|                     ) | ||||
|  | ||||
|                     // Load length of `nestedAssetData[i]` | ||||
|                     let nestedAssetDataElementLenStart := sub(nestedAssetDataElementContentsStart, 32) | ||||
|   | ||||
							
								
								
									
										83
									
								
								contracts/asset-proxy/contracts/src/StaticCallProxy.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								contracts/asset-proxy/contracts/src/StaticCallProxy.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| /* | ||||
|  | ||||
|   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.5.9; | ||||
|  | ||||
| import "@0x/contracts-utils/contracts/src/LibBytes.sol"; | ||||
|  | ||||
|  | ||||
| // solhint-disable no-unused-vars | ||||
| contract StaticCallProxy { | ||||
|  | ||||
|     using LibBytes for bytes; | ||||
|  | ||||
|     // Id of this proxy. | ||||
|     bytes4 constant internal PROXY_ID = bytes4(keccak256("StaticCall(address,bytes,bytes32)")); | ||||
|  | ||||
|     /// @dev Makes a staticcall to a target address and verifies that the data returned matches the expected return data. | ||||
|     /// @param assetData Byte array encoded with staticCallTarget, staticCallData, and expectedCallResultHash | ||||
|     /// @param from This value is ignored. | ||||
|     /// @param to This value is ignored. | ||||
|     /// @param amount This value is ignored. | ||||
|     function transferFrom( | ||||
|         bytes calldata assetData, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|     { | ||||
|         // Decode params from `assetData` | ||||
|         ( | ||||
|             address staticCallTarget, | ||||
|             bytes memory staticCallData, | ||||
|             bytes32 expectedReturnDataHash | ||||
|         ) = abi.decode( | ||||
|             assetData.sliceDestructive(4, assetData.length), | ||||
|             (address, bytes, bytes32) | ||||
|         ); | ||||
|  | ||||
|         // Execute staticcall | ||||
|         (bool success, bytes memory returnData) = staticCallTarget.staticcall(staticCallData); | ||||
|  | ||||
|         // Revert with returned data if staticcall is unsuccessful | ||||
|         if (!success) { | ||||
|             assembly { | ||||
|                 revert(add(returnData, 32), mload(returnData)) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Revert if hash of return data is not as expected | ||||
|         bytes32 returnDataHash = keccak256(returnData); | ||||
|         require( | ||||
|             expectedReturnDataHash == returnDataHash, | ||||
|             "UNEXPECTED_STATIC_CALL_RESULT" | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Gets the proxy id associated with the proxy address. | ||||
|     /// @return Proxy id. | ||||
|     function getProxyId() | ||||
|         external | ||||
|         pure | ||||
|         returns (bytes4) | ||||
|     { | ||||
|         return PROXY_ID; | ||||
|     } | ||||
| } | ||||
| @@ -26,19 +26,33 @@ pragma experimental ABIEncoderV2; | ||||
| // This argument is ABI encoded as one of the methods of this interface. | ||||
| interface IAssetData { | ||||
|  | ||||
|     function ERC20Token(address tokenContract) | ||||
|     function ERC20Token(address tokenAddress) | ||||
|         external; | ||||
|      | ||||
|     function ERC721Token( | ||||
|         address tokenContract, | ||||
|         address tokenAddress, | ||||
|         uint256 tokenId | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     function ERC1155Assets( | ||||
|         address tokenAddress, | ||||
|         uint256[] calldata tokenIds, | ||||
|         uint256[] calldata tokenValues, | ||||
|         bytes calldata callbackData | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     function MultiAsset( | ||||
|         uint256[] calldata amounts, | ||||
|         bytes[] calldata nestedAssetData | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     function StaticCall( | ||||
|         address callTarget, | ||||
|         bytes calldata staticCallData, | ||||
|         bytes32 callResultHash | ||||
|     ) | ||||
|         external; | ||||
| } | ||||
|   | ||||
| @@ -21,9 +21,8 @@ pragma solidity ^0.5.5; | ||||
| import "./IAuthorizable.sol"; | ||||
|  | ||||
|  | ||||
| contract IAssetProxy is | ||||
|     IAuthorizable | ||||
| { | ||||
| contract IAssetProxy { | ||||
|  | ||||
|     /// @dev Transfers assets. Either succeeds or throws. | ||||
|     /// @param assetData Byte array encoded for the respective asset proxy. | ||||
|     /// @param from Address to transfer asset from. | ||||
|   | ||||
| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2019 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.5.5; | ||||
|  | ||||
|  | ||||
| contract LibAssetProxyIds { | ||||
|  | ||||
|     // AssetProxy Ids are equiavalent the first 4 bytes of the keccak256 hash of the function signature assigned to each AssetProxy. | ||||
|  | ||||
|     // ERC20Token(address) | ||||
|     bytes4 constant public ERC20_PROXY_ID = 0xf47261b0; | ||||
|  | ||||
|     // ERC721Token(address,uint256) | ||||
|     bytes4 constant public ERC721_PROXY_ID = 0x02571792; | ||||
|  | ||||
|     // ERC1155Assets(address,uint256[],uint256[],bytes) | ||||
|     bytes4 constant public ERC1155_PROXY_ID = 0xa7cb5fb7; | ||||
|  | ||||
|     // MultiAsset(uint256[],bytes[]) | ||||
|     bytes4 constant public MULTI_ASSET_PROXY_ID = 0x94cfcdd7; | ||||
|  | ||||
|     // StaticCall(address,bytes,bytes32) | ||||
|     bytes4 constant public STATIC_CALL_PROXY_ID = 0xc339d10a; | ||||
| } | ||||
| @@ -0,0 +1,82 @@ | ||||
| /* | ||||
|  | ||||
|   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.5.9; | ||||
|  | ||||
| import "@0x/contracts-utils/contracts/src/LibBytes.sol"; | ||||
|  | ||||
|  | ||||
| contract TestStaticCallTarget { | ||||
|  | ||||
|     using LibBytes for bytes; | ||||
|  | ||||
|     uint256 internal _state; | ||||
|   | ||||
|     function updateState() | ||||
|         external | ||||
|     { | ||||
|         _state++; | ||||
|     } | ||||
|  | ||||
|     function assertEvenNumber(uint256 target) | ||||
|         external | ||||
|         pure | ||||
|     { | ||||
|         require( | ||||
|             target % 2 == 0, | ||||
|             "TARGET_NOT_EVEN" | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function isOddNumber(uint256 target) | ||||
|         external | ||||
|         pure | ||||
|         returns (bool isOdd) | ||||
|     { | ||||
|         isOdd = target % 2 == 1; | ||||
|         return isOdd; | ||||
|     } | ||||
|  | ||||
|     function noInputFunction() | ||||
|         external | ||||
|         pure | ||||
|     { | ||||
|         assert(msg.data.length == 4 && msg.data.readBytes4(0) == bytes4(keccak256("noInputFunction()"))); | ||||
|     } | ||||
|  | ||||
|     function dynamicInputFunction(bytes calldata a) | ||||
|         external | ||||
|         pure | ||||
|     { | ||||
|         bytes memory abiEncodedData = abi.encodeWithSignature("dynamicInputFunction(bytes)", a); | ||||
|         assert(msg.data.equals(abiEncodedData)); | ||||
|     } | ||||
|  | ||||
|     function returnComplexType(uint256 a, uint256 b) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes memory result) | ||||
|     { | ||||
|         result = abi.encodePacked( | ||||
|             address(this), | ||||
|             a, | ||||
|             b | ||||
|         ); | ||||
|         return result; | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-asset-proxy", | ||||
|     "version": "2.1.1", | ||||
|     "version": "2.2.5", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -34,7 +34,7 @@ | ||||
|         "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol" | ||||
|     }, | ||||
|     "config": { | ||||
|         "abis": "./generated-artifacts/@(ERC1155Proxy|ERC20Proxy|ERC721Proxy|IAssetData|IAssetProxy|IAuthorizable|MixinAuthorizable|MultiAssetProxy).json", | ||||
|         "abis": "./generated-artifacts/@(ERC1155Proxy|ERC20Proxy|ERC721Proxy|IAssetData|IAssetProxy|IAuthorizable|MixinAuthorizable|MultiAssetProxy|StaticCallProxy|TestStaticCallTarget).json", | ||||
|         "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually." | ||||
|     }, | ||||
|     "repository": { | ||||
| @@ -47,20 +47,21 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^2.0.9", | ||||
|         "@0x/contracts-gen": "^1.0.8", | ||||
|         "@0x/contracts-test-utils": "^3.1.2", | ||||
|         "@0x/dev-utils": "^2.2.1", | ||||
|         "@0x/sol-compiler": "^3.1.6", | ||||
|         "@0x/abi-gen": "^4.1.0", | ||||
|         "@0x/contracts-gen": "^1.0.13", | ||||
|         "@0x/contracts-test-utils": "^3.1.13", | ||||
|         "@0x/dev-utils": "^2.3.0", | ||||
|         "@0x/sol-compiler": "^3.1.12", | ||||
|         "@0x/tslint-config": "^3.0.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^4.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
|         "solhint": "^1.4.1", | ||||
| @@ -68,17 +69,18 @@ | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^5.0.5", | ||||
|         "@0x/contracts-erc1155": "^1.1.1", | ||||
|         "@0x/contracts-erc20": "^2.2.0", | ||||
|         "@0x/contracts-erc721": "^2.1.1", | ||||
|         "@0x/contracts-utils": "^3.1.1", | ||||
|         "@0x/order-utils": "^7.2.0", | ||||
|         "@0x/types": "^2.2.2", | ||||
|         "@0x/typescript-typings": "^4.2.2", | ||||
|         "@0x/utils": "^4.3.1", | ||||
|         "@0x/web3-wrapper": "^6.0.5", | ||||
|         "ethereum-types": "^2.1.2", | ||||
|         "@0x/base-contract": "^5.3.1", | ||||
|         "@0x/contracts-erc1155": "^1.1.12", | ||||
|         "@0x/contracts-erc20": "^2.2.11", | ||||
|         "@0x/contracts-erc721": "^2.1.12", | ||||
|         "@0x/contracts-utils": "^3.2.1", | ||||
|         "@0x/order-utils": "^8.2.5", | ||||
|         "@0x/types": "^2.4.1", | ||||
|         "@0x/typescript-typings": "^4.2.4", | ||||
|         "@0x/utils": "^4.5.0", | ||||
|         "@0x/web3-wrapper": "^6.0.10", | ||||
|         "ethereum-types": "^2.1.4", | ||||
|         "ethereumjs-util": "^5.1.1", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -13,13 +13,17 @@ import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json'; | ||||
| import * as IAuthorizable from '../generated-artifacts/IAuthorizable.json'; | ||||
| import * as MixinAuthorizable from '../generated-artifacts/MixinAuthorizable.json'; | ||||
| import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json'; | ||||
| import * as StaticCallProxy from '../generated-artifacts/StaticCallProxy.json'; | ||||
| import * as TestStaticCallTarget from '../generated-artifacts/TestStaticCallTarget.json'; | ||||
| export const artifacts = { | ||||
|     ERC1155Proxy: ERC1155Proxy as ContractArtifact, | ||||
|     ERC20Proxy: ERC20Proxy as ContractArtifact, | ||||
|     ERC721Proxy: ERC721Proxy as ContractArtifact, | ||||
|     ERC1155Proxy: ERC1155Proxy as ContractArtifact, | ||||
|     MixinAuthorizable: MixinAuthorizable as ContractArtifact, | ||||
|     MultiAssetProxy: MultiAssetProxy as ContractArtifact, | ||||
|     StaticCallProxy: StaticCallProxy as ContractArtifact, | ||||
|     IAssetData: IAssetData as ContractArtifact, | ||||
|     IAssetProxy: IAssetProxy as ContractArtifact, | ||||
|     IAuthorizable: IAuthorizable as ContractArtifact, | ||||
|     TestStaticCallTarget: TestStaticCallTarget as ContractArtifact, | ||||
| }; | ||||
|   | ||||
| @@ -11,3 +11,5 @@ export * from '../generated-wrappers/i_asset_proxy'; | ||||
| export * from '../generated-wrappers/i_authorizable'; | ||||
| export * from '../generated-wrappers/mixin_authorizable'; | ||||
| export * from '../generated-wrappers/multi_asset_proxy'; | ||||
| export * from '../generated-wrappers/static_call_proxy'; | ||||
| export * from '../generated-wrappers/test_static_call_target'; | ||||
|   | ||||
| @@ -37,6 +37,7 @@ describe('Authorizable', () => { | ||||
|             artifacts.MixinAuthorizable, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|     }); | ||||
|     beforeEach(async () => { | ||||
| @@ -53,16 +54,18 @@ describe('Authorizable', () => { | ||||
|             ); | ||||
|         }); | ||||
|         it('should allow owner to add an authorized address', async () => { | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), | ||||
|             await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             const isAuthorized = await authorizable.authorized.callAsync(address); | ||||
|             expect(isAuthorized).to.be.true(); | ||||
|         }); | ||||
|         it('should throw if owner attempts to authorize a duplicate address', async () => { | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), | ||||
|             await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             return expectTransactionFailedAsync( | ||||
| @@ -74,8 +77,9 @@ describe('Authorizable', () => { | ||||
|  | ||||
|     describe('removeAuthorizedAddress', () => { | ||||
|         it('should throw if not called by owner', async () => { | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), | ||||
|             await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             return expectTransactionFailedAsync( | ||||
| @@ -87,14 +91,14 @@ describe('Authorizable', () => { | ||||
|         }); | ||||
|  | ||||
|         it('should allow owner to remove an authorized address', async () => { | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), | ||||
|             await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.removeAuthorizedAddress.sendTransactionAsync(address, { | ||||
|                     from: owner, | ||||
|                 }), | ||||
|             await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             const isAuthorized = await authorizable.authorized.callAsync(address); | ||||
| @@ -113,8 +117,9 @@ describe('Authorizable', () => { | ||||
|  | ||||
|     describe('removeAuthorizedAddressAtIndex', () => { | ||||
|         it('should throw if not called by owner', async () => { | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), | ||||
|             await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             const index = new BigNumber(0); | ||||
| @@ -126,8 +131,9 @@ describe('Authorizable', () => { | ||||
|             ); | ||||
|         }); | ||||
|         it('should throw if index is >= authorities.length', async () => { | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), | ||||
|             await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             const index = new BigNumber(1); | ||||
| @@ -150,12 +156,14 @@ describe('Authorizable', () => { | ||||
|         it('should throw if address at index does not match target', async () => { | ||||
|             const address1 = address; | ||||
|             const address2 = notOwner; | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.addAuthorizedAddress.sendTransactionAsync(address1, { from: owner }), | ||||
|             await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address1, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.addAuthorizedAddress.sendTransactionAsync(address2, { from: owner }), | ||||
|             await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address2, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             const address1Index = new BigNumber(0); | ||||
| @@ -167,15 +175,16 @@ describe('Authorizable', () => { | ||||
|             ); | ||||
|         }); | ||||
|         it('should allow owner to remove an authorized address', async () => { | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), | ||||
|             await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             const index = new BigNumber(0); | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, { | ||||
|                     from: owner, | ||||
|                 }), | ||||
|             await authorizable.removeAuthorizedAddressAtIndex.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 index, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             const isAuthorized = await authorizable.authorized.callAsync(address); | ||||
| @@ -187,20 +196,17 @@ describe('Authorizable', () => { | ||||
|         it('should return all authorized addresses', async () => { | ||||
|             const initial = await authorizable.getAuthorizedAddresses.callAsync(); | ||||
|             expect(initial).to.have.length(0); | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { | ||||
|                     from: owner, | ||||
|                 }), | ||||
|             await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             const afterAdd = await authorizable.getAuthorizedAddresses.callAsync(); | ||||
|             expect(afterAdd).to.have.length(1); | ||||
|             expect(afterAdd).to.include(address); | ||||
|  | ||||
|             await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                 await authorizable.removeAuthorizedAddress.sendTransactionAsync(address, { | ||||
|                     from: owner, | ||||
|                 }), | ||||
|             await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|                 address, | ||||
|                 { from: owner }, | ||||
|                 constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|             ); | ||||
|             const afterRemove = await authorizable.getAuthorizedAddresses.callAsync(); | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -23,7 +23,7 @@ import { | ||||
| } from '@0x/contracts-test-utils'; | ||||
| import { BlockchainLifecycle } from '@0x/dev-utils'; | ||||
| import { assetDataUtils } from '@0x/order-utils'; | ||||
| import { RevertReason } from '@0x/types'; | ||||
| import { AssetProxyId, RevertReason } from '@0x/types'; | ||||
| import { BigNumber } from '@0x/utils'; | ||||
| import * as chai from 'chai'; | ||||
| import { LogWithDecodedArgs } from 'ethereum-types'; | ||||
| @@ -31,6 +31,7 @@ import * as _ from 'lodash'; | ||||
|  | ||||
| import { | ||||
|     artifacts, | ||||
|     ERC1155ProxyContract, | ||||
|     ERC1155ProxyWrapper, | ||||
|     ERC20ProxyContract, | ||||
|     ERC20Wrapper, | ||||
| @@ -44,16 +45,8 @@ import { | ||||
| chaiSetup.configure(); | ||||
| const expect = chai.expect; | ||||
| const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); | ||||
| const assetProxyInterface = new IAssetProxyContract( | ||||
|     artifacts.IAssetProxy.compilerOutput.abi, | ||||
|     constants.NULL_ADDRESS, | ||||
|     provider, | ||||
| ); | ||||
| const assetDataInterface = new IAssetDataContract( | ||||
|     artifacts.IAssetData.compilerOutput.abi, | ||||
|     constants.NULL_ADDRESS, | ||||
|     provider, | ||||
| ); | ||||
| const assetProxyInterface = new IAssetProxyContract(constants.NULL_ADDRESS, provider); | ||||
| const assetDataInterface = new IAssetDataContract(constants.NULL_ADDRESS, provider); | ||||
|  | ||||
| // tslint:disable:no-unnecessary-type-assertion | ||||
| describe('Asset Transfer Proxies', () => { | ||||
| @@ -79,7 +72,7 @@ describe('Asset Transfer Proxies', () => { | ||||
|     let erc721AFromTokenId: BigNumber; | ||||
|     let erc721BFromTokenId: BigNumber; | ||||
|  | ||||
|     let erc1155Proxy: ERC721ProxyContract; | ||||
|     let erc1155Proxy: ERC1155ProxyContract; | ||||
|     let erc1155ProxyWrapper: ERC1155ProxyWrapper; | ||||
|     let erc1155Contract: ERC1155MintableContract; | ||||
|     let erc1155Contract2: ERC1155MintableContract; | ||||
| @@ -108,75 +101,66 @@ describe('Asset Transfer Proxies', () => { | ||||
|             artifacts.MultiAssetProxy, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|  | ||||
|         // Configure ERC20Proxy | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, { | ||||
|                 from: owner, | ||||
|             }), | ||||
|         await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|             authorized, | ||||
|             { from: owner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, { | ||||
|                 from: owner, | ||||
|             }), | ||||
|         await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|             multiAssetProxy.address, | ||||
|             { from: owner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|  | ||||
|         // Configure ERC721Proxy | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, { | ||||
|                 from: owner, | ||||
|             }), | ||||
|         await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|             authorized, | ||||
|             { from: owner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, { | ||||
|                 from: owner, | ||||
|             }), | ||||
|         await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|             multiAssetProxy.address, | ||||
|             { from: owner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|  | ||||
|         // Configure ERC115Proxy | ||||
|         erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner); | ||||
|         erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync(); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, { | ||||
|                 from: owner, | ||||
|             }), | ||||
|         await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|             authorized, | ||||
|             { from: owner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, { | ||||
|                 from: owner, | ||||
|             }), | ||||
|         await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|             multiAssetProxy.address, | ||||
|             { from: owner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|  | ||||
|         // Configure MultiAssetProxy | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await multiAssetProxy.addAuthorizedAddress.sendTransactionAsync(authorized, { | ||||
|                 from: owner, | ||||
|             }), | ||||
|         await multiAssetProxy.addAuthorizedAddress.awaitTransactionSuccessAsync( | ||||
|             authorized, | ||||
|             { from: owner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, { | ||||
|                 from: owner, | ||||
|             }), | ||||
|         await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync( | ||||
|             erc20Proxy.address, | ||||
|             { from: owner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc721Proxy.address, { | ||||
|                 from: owner, | ||||
|             }), | ||||
|         await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync( | ||||
|             erc721Proxy.address, | ||||
|             { from: owner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc1155Proxy.address, { | ||||
|                 from: owner, | ||||
|             }), | ||||
|         await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync( | ||||
|             erc1155Proxy.address, | ||||
|             { from: owner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|  | ||||
| @@ -190,6 +174,7 @@ describe('Asset Transfer Proxies', () => { | ||||
|             erc20Artifacts.DummyNoReturnERC20Token, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             constants.DUMMY_TOKEN_NAME, | ||||
|             constants.DUMMY_TOKEN_SYMBOL, | ||||
|             constants.DUMMY_TOKEN_DECIMALS, | ||||
| @@ -199,6 +184,7 @@ describe('Asset Transfer Proxies', () => { | ||||
|             erc20Artifacts.DummyMultipleReturnERC20Token, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             constants.DUMMY_TOKEN_NAME, | ||||
|             constants.DUMMY_TOKEN_SYMBOL, | ||||
|             constants.DUMMY_TOKEN_DECIMALS, | ||||
| @@ -206,31 +192,32 @@ describe('Asset Transfer Proxies', () => { | ||||
|         ); | ||||
|  | ||||
|         await erc20Wrapper.setBalancesAndAllowancesAsync(); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await noReturnErc20Token.setBalance.sendTransactionAsync(fromAddress, constants.INITIAL_ERC20_BALANCE), | ||||
|         await noReturnErc20Token.setBalance.awaitTransactionSuccessAsync( | ||||
|             fromAddress, | ||||
|             constants.INITIAL_ERC20_BALANCE, | ||||
|             { | ||||
|                 from: owner, | ||||
|             }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await noReturnErc20Token.approve.sendTransactionAsync( | ||||
|                 erc20Proxy.address, | ||||
|                 constants.INITIAL_ERC20_ALLOWANCE, | ||||
|                 { from: fromAddress }, | ||||
|             ), | ||||
|         await noReturnErc20Token.approve.awaitTransactionSuccessAsync( | ||||
|             erc20Proxy.address, | ||||
|             constants.INITIAL_ERC20_ALLOWANCE, | ||||
|             { from: fromAddress }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await multipleReturnErc20Token.setBalance.sendTransactionAsync( | ||||
|                 fromAddress, | ||||
|                 constants.INITIAL_ERC20_BALANCE, | ||||
|             ), | ||||
|         await multipleReturnErc20Token.setBalance.awaitTransactionSuccessAsync( | ||||
|             fromAddress, | ||||
|             constants.INITIAL_ERC20_BALANCE, | ||||
|             { | ||||
|                 from: owner, | ||||
|             }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await multipleReturnErc20Token.approve.sendTransactionAsync( | ||||
|                 erc20Proxy.address, | ||||
|                 constants.INITIAL_ERC20_ALLOWANCE, | ||||
|                 { from: fromAddress }, | ||||
|             ), | ||||
|         await multipleReturnErc20Token.approve.awaitTransactionSuccessAsync( | ||||
|             erc20Proxy.address, | ||||
|             constants.INITIAL_ERC20_ALLOWANCE, | ||||
|             { from: fromAddress }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|  | ||||
| @@ -240,6 +227,7 @@ describe('Asset Transfer Proxies', () => { | ||||
|             erc721Artifacts.DummyERC721Receiver, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|  | ||||
|         await erc721Wrapper.setBalancesAndAllowancesAsync(); | ||||
| @@ -419,10 +407,10 @@ describe('Asset Transfer Proxies', () => { | ||||
|                     toAddress, | ||||
|                     amount, | ||||
|                 ); | ||||
|                 await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                     await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, allowance, { | ||||
|                         from: fromAddress, | ||||
|                     }), | ||||
|                 await erc20TokenA.approve.awaitTransactionSuccessAsync( | ||||
|                     erc20Proxy.address, | ||||
|                     allowance, | ||||
|                     { from: fromAddress }, | ||||
|                     constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|                 ); | ||||
|                 const erc20Balances = await erc20Wrapper.getBalancesAsync(); | ||||
| @@ -451,10 +439,10 @@ describe('Asset Transfer Proxies', () => { | ||||
|                     toAddress, | ||||
|                     amount, | ||||
|                 ); | ||||
|                 await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                     await noReturnErc20Token.approve.sendTransactionAsync(erc20Proxy.address, allowance, { | ||||
|                         from: fromAddress, | ||||
|                     }), | ||||
|                 await noReturnErc20Token.approve.awaitTransactionSuccessAsync( | ||||
|                     erc20Proxy.address, | ||||
|                     allowance, | ||||
|                     { from: fromAddress }, | ||||
|                     constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|                 ); | ||||
|                 const initialFromBalance = await noReturnErc20Token.balanceOf.callAsync(fromAddress); | ||||
| @@ -692,10 +680,10 @@ describe('Asset Transfer Proxies', () => { | ||||
|                 const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId); | ||||
|                 expect(ownerFromAsset).to.be.equal(fromAddress); | ||||
|                 // Remove transfer approval for fromAddress. | ||||
|                 await web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                     await erc721TokenA.approve.sendTransactionAsync(constants.NULL_ADDRESS, erc721AFromTokenId, { | ||||
|                         from: fromAddress, | ||||
|                     }), | ||||
|                 await erc721TokenA.approve.awaitTransactionSuccessAsync( | ||||
|                     constants.NULL_ADDRESS, | ||||
|                     erc721AFromTokenId, | ||||
|                     { from: fromAddress }, | ||||
|                     constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|                 ); | ||||
|                 // Perform a transfer; expect this to fail. | ||||
| @@ -1346,7 +1334,7 @@ describe('Asset Transfer Proxies', () => { | ||||
|                 const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); | ||||
|                 const amounts = [erc20Amount, erc721Amount]; | ||||
|                 const nestedAssetData = [erc20AssetData, erc721AssetData]; | ||||
|                 const extraData = '0102030405060708'; | ||||
|                 const extraData = '0102030405060708090001020304050607080900010203040506070809000102'; | ||||
|                 const assetData = `${assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData)}${extraData}`; | ||||
|                 const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( | ||||
|                     assetData, | ||||
| @@ -1641,6 +1629,120 @@ describe('Asset Transfer Proxies', () => { | ||||
|                     RevertReason.SenderNotAuthorized, | ||||
|                 ); | ||||
|             }); | ||||
|             it('should revert if asset data overflows beyond the bounds of calldata', async () => { | ||||
|                 const inputAmount = new BigNumber(1); | ||||
|                 const erc20Amount = new BigNumber(10); | ||||
|                 const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); | ||||
|                 const erc721Amount = new BigNumber(1); | ||||
|                 const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); | ||||
|                 const amounts = [erc20Amount, erc721Amount]; | ||||
|                 const nestedAssetData = [erc20AssetData, erc721AssetData]; | ||||
|                 const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); | ||||
|                 const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( | ||||
|                     assetData, | ||||
|                     fromAddress, | ||||
|                     toAddress, | ||||
|                     inputAmount, | ||||
|                 ); | ||||
|                 // append asset data to end of tx data with a length of 0x300 bytes, which will extend past actual calldata. | ||||
|                 const offsetToAssetData = '0000000000000000000000000000000000000000000000000000000000000080'; | ||||
|                 const invalidOffsetToAssetData = '00000000000000000000000000000000000000000000000000000000000002a0'; | ||||
|                 const newAssetData = '0000000000000000000000000000000000000000000000000000000000000304'; | ||||
|                 const badData = `${data.replace(offsetToAssetData, invalidOffsetToAssetData)}${newAssetData}`; | ||||
|                 // execute transfer | ||||
|                 await expectTransactionFailedAsync( | ||||
|                     web3Wrapper.sendTransactionAsync({ | ||||
|                         to: multiAssetProxy.address, | ||||
|                         data: badData, | ||||
|                         from: authorized, | ||||
|                     }), | ||||
|                     RevertReason.InvalidAssetDataEnd, | ||||
|                 ); | ||||
|             }); | ||||
|             it('should revert if asset data resolves to a location beyond the bounds of calldata', async () => { | ||||
|                 const inputAmount = new BigNumber(1); | ||||
|                 const erc20Amount = new BigNumber(10); | ||||
|                 const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); | ||||
|                 const erc721Amount = new BigNumber(1); | ||||
|                 const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); | ||||
|                 const amounts = [erc20Amount, erc721Amount]; | ||||
|                 const nestedAssetData = [erc20AssetData, erc721AssetData]; | ||||
|                 const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); | ||||
|                 const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( | ||||
|                     assetData, | ||||
|                     fromAddress, | ||||
|                     toAddress, | ||||
|                     inputAmount, | ||||
|                 ); | ||||
|                 const offsetToAssetData = '0000000000000000000000000000000000000000000000000000000000000080'; | ||||
|                 const invalidOffsetToAssetData = '0000000000000000000000000000000000000000000000000000000000000400'; | ||||
|                 const badData = data.replace(offsetToAssetData, invalidOffsetToAssetData); | ||||
|                 // execute transfer | ||||
|                 // note that this triggers `InvalidAssetDataLength` because the length is zero, otherwise it would | ||||
|                 // trigger `InvalidAssetDataEnd`. | ||||
|                 await expectTransactionFailedAsync( | ||||
|                     web3Wrapper.sendTransactionAsync({ | ||||
|                         to: multiAssetProxy.address, | ||||
|                         data: badData, | ||||
|                         from: authorized, | ||||
|                     }), | ||||
|                     RevertReason.InvalidAssetDataLength, | ||||
|                 ); | ||||
|             }); | ||||
|             it('should revert if length of assetData, excluding the selector, is not a multiple of 32', async () => { | ||||
|                 // setup test parameters | ||||
|                 const inputAmount = new BigNumber(1); | ||||
|                 const erc20Amount = new BigNumber(10); | ||||
|                 const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); | ||||
|                 const erc721Amount = new BigNumber(1); | ||||
|                 const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); | ||||
|                 const amounts = [erc20Amount, erc721Amount]; | ||||
|                 const nestedAssetData = [erc20AssetData, erc721AssetData]; | ||||
|                 const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); | ||||
|                 const extraData = '01'; | ||||
|                 const assetDataWithExtraData = `${assetData}${extraData}`; | ||||
|                 const badData = assetProxyInterface.transferFrom.getABIEncodedTransactionData( | ||||
|                     assetDataWithExtraData, | ||||
|                     fromAddress, | ||||
|                     toAddress, | ||||
|                     inputAmount, | ||||
|                 ); | ||||
|                 // execute transfer | ||||
|                 await expectTransactionFailedAsync( | ||||
|                     web3Wrapper.sendTransactionAsync({ | ||||
|                         to: multiAssetProxy.address, | ||||
|                         data: badData, | ||||
|                         from: authorized, | ||||
|                     }), | ||||
|                     RevertReason.InvalidAssetDataLength, | ||||
|                 ); | ||||
|             }); | ||||
|             it('should revert if length of assetData is less than 68 bytes', async () => { | ||||
|                 // setup test parameters | ||||
|                 const inputAmount = new BigNumber(1); | ||||
|                 // we'll construct asset data that has a 4 byte selector plus | ||||
|                 // 32 byte payload. This results in asset data that is 36 bytes | ||||
|                 // long and will trigger the `invalid length` error. | ||||
|                 // we must be sure to use a # of bytes that is still %32 | ||||
|                 // so that we know the error is not triggered by another check in the code. | ||||
|                 const zeros32Bytes = '0'.repeat(64); | ||||
|                 const assetData36Bytes = `${AssetProxyId.MultiAsset}${zeros32Bytes}`; | ||||
|                 const badData = assetProxyInterface.transferFrom.getABIEncodedTransactionData( | ||||
|                     assetData36Bytes, | ||||
|                     fromAddress, | ||||
|                     toAddress, | ||||
|                     inputAmount, | ||||
|                 ); | ||||
|                 // execute transfer | ||||
|                 await expectTransactionFailedAsync( | ||||
|                     web3Wrapper.sendTransactionAsync({ | ||||
|                         to: multiAssetProxy.address, | ||||
|                         data: badData, | ||||
|                         from: authorized, | ||||
|                     }), | ||||
|                     RevertReason.InvalidAssetDataLength, | ||||
|                 ); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
|   | ||||
							
								
								
									
										242
									
								
								contracts/asset-proxy/test/static_call_proxy.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								contracts/asset-proxy/test/static_call_proxy.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,242 @@ | ||||
| import { | ||||
|     chaiSetup, | ||||
|     constants, | ||||
|     expectTransactionFailedAsync, | ||||
|     expectTransactionFailedWithoutReasonAsync, | ||||
|     provider, | ||||
|     txDefaults, | ||||
|     web3Wrapper, | ||||
| } from '@0x/contracts-test-utils'; | ||||
| import { BlockchainLifecycle } from '@0x/dev-utils'; | ||||
| import { assetDataUtils } from '@0x/order-utils'; | ||||
| import { AssetProxyId, RevertReason } from '@0x/types'; | ||||
| import { AbiEncoder, BigNumber } from '@0x/utils'; | ||||
| import * as chai from 'chai'; | ||||
| import * as ethUtil from 'ethereumjs-util'; | ||||
|  | ||||
| import { artifacts, IAssetProxyContract, StaticCallProxyContract, TestStaticCallTargetContract } from '../src'; | ||||
|  | ||||
| chaiSetup.configure(); | ||||
| const expect = chai.expect; | ||||
| const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); | ||||
|  | ||||
| describe('StaticCallProxy', () => { | ||||
|     const amount = constants.ZERO_AMOUNT; | ||||
|     let fromAddress: string; | ||||
|     let toAddress: string; | ||||
|  | ||||
|     let staticCallProxy: IAssetProxyContract; | ||||
|     let staticCallTarget: TestStaticCallTargetContract; | ||||
|  | ||||
|     before(async () => { | ||||
|         await blockchainLifecycle.startAsync(); | ||||
|     }); | ||||
|     after(async () => { | ||||
|         await blockchainLifecycle.revertAsync(); | ||||
|     }); | ||||
|     before(async () => { | ||||
|         const accounts = await web3Wrapper.getAvailableAddressesAsync(); | ||||
|         [fromAddress, toAddress] = accounts.slice(0, 2); | ||||
|         const staticCallProxyWithoutTransferFrom = await StaticCallProxyContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.StaticCallProxy, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         staticCallProxy = new IAssetProxyContract(staticCallProxyWithoutTransferFrom.address, provider, txDefaults); | ||||
|         staticCallTarget = await TestStaticCallTargetContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.TestStaticCallTarget, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|     }); | ||||
|     beforeEach(async () => { | ||||
|         await blockchainLifecycle.startAsync(); | ||||
|     }); | ||||
|     afterEach(async () => { | ||||
|         await blockchainLifecycle.revertAsync(); | ||||
|     }); | ||||
|  | ||||
|     describe('general', () => { | ||||
|         it('should revert if undefined function is called', async () => { | ||||
|             const undefinedSelector = '0x01020304'; | ||||
|             await expectTransactionFailedWithoutReasonAsync( | ||||
|                 web3Wrapper.sendTransactionAsync({ | ||||
|                     from: fromAddress, | ||||
|                     to: staticCallProxy.address, | ||||
|                     value: constants.ZERO_AMOUNT, | ||||
|                     data: undefinedSelector, | ||||
|                 }), | ||||
|             ); | ||||
|         }); | ||||
|         it('should have an id of 0xc339d10a', async () => { | ||||
|             const proxyId = await staticCallProxy.getProxyId.callAsync(); | ||||
|             const expectedProxyId = AssetProxyId.StaticCall; | ||||
|             expect(proxyId).to.equal(expectedProxyId); | ||||
|         }); | ||||
|     }); | ||||
|     describe('transferFrom', () => { | ||||
|         it('should revert if assetData lies outside the bounds of calldata', async () => { | ||||
|             const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData(); | ||||
|             const expectedResultHash = constants.KECCAK256_NULL; | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             const txData = staticCallProxy.transferFrom.getABIEncodedTransactionData( | ||||
|                 assetData, | ||||
|                 fromAddress, | ||||
|                 toAddress, | ||||
|                 amount, | ||||
|             ); | ||||
|             const offsetToAssetData = '0000000000000000000000000000000000000000000000000000000000000080'; | ||||
|             const txDataEndBuffer = ethUtil.toBuffer((txData.length - 2) / 2 - 4); | ||||
|             const paddedTxDataEndBuffer = ethUtil.setLengthLeft(txDataEndBuffer, 32); | ||||
|             const invalidOffsetToAssetData = ethUtil.bufferToHex(paddedTxDataEndBuffer).slice(2); | ||||
|             const newAssetData = '0000000000000000000000000000000000000000000000000000000000000304'; | ||||
|             const badTxData = `${txData.replace(offsetToAssetData, invalidOffsetToAssetData)}${newAssetData}`; | ||||
|             await expectTransactionFailedWithoutReasonAsync( | ||||
|                 web3Wrapper.sendTransactionAsync({ | ||||
|                     to: staticCallProxy.address, | ||||
|                     from: fromAddress, | ||||
|                     data: badTxData, | ||||
|                 }), | ||||
|             ); | ||||
|         }); | ||||
|         it('should revert if the length of assetData is less than 100 bytes', async () => { | ||||
|             const staticCallData = constants.NULL_BYTES; | ||||
|             const expectedResultHash = constants.KECCAK256_NULL; | ||||
|             const assetData = assetDataUtils | ||||
|                 .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash) | ||||
|                 .slice(0, -128); | ||||
|             const assetDataByteLen = (assetData.length - 2) / 2; | ||||
|             expect((assetDataByteLen - 4) % 32).to.equal(0); | ||||
|             await expectTransactionFailedWithoutReasonAsync( | ||||
|                 staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount), | ||||
|             ); | ||||
|         }); | ||||
|         it('should revert if the offset to `staticCallData` points to outside of assetData', async () => { | ||||
|             const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData(); | ||||
|             const expectedResultHash = constants.KECCAK256_NULL; | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             const offsetToStaticCallData = '0000000000000000000000000000000000000000000000000000000000000060'; | ||||
|             const assetDataEndBuffer = ethUtil.toBuffer((assetData.length - 2) / 2 - 4); | ||||
|             const paddedAssetDataEndBuffer = ethUtil.setLengthLeft(assetDataEndBuffer, 32); | ||||
|             const invalidOffsetToStaticCallData = ethUtil.bufferToHex(paddedAssetDataEndBuffer).slice(2); | ||||
|             const newStaticCallData = '0000000000000000000000000000000000000000000000000000000000000304'; | ||||
|             const badAssetData = `${assetData.replace( | ||||
|                 offsetToStaticCallData, | ||||
|                 invalidOffsetToStaticCallData, | ||||
|             )}${newStaticCallData}`; | ||||
|             await expectTransactionFailedWithoutReasonAsync( | ||||
|                 staticCallProxy.transferFrom.sendTransactionAsync(badAssetData, fromAddress, toAddress, amount), | ||||
|             ); | ||||
|         }); | ||||
|         it('should revert if the callTarget attempts to write to state', async () => { | ||||
|             const staticCallData = staticCallTarget.updateState.getABIEncodedTransactionData(); | ||||
|             const expectedResultHash = constants.KECCAK256_NULL; | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             await expectTransactionFailedWithoutReasonAsync( | ||||
|                 staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount), | ||||
|             ); | ||||
|         }); | ||||
|         it('should revert with data provided by the callTarget if the staticcall reverts', async () => { | ||||
|             const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(new BigNumber(1)); | ||||
|             const expectedResultHash = constants.KECCAK256_NULL; | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             await expectTransactionFailedAsync( | ||||
|                 staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount), | ||||
|                 RevertReason.TargetNotEven, | ||||
|             ); | ||||
|         }); | ||||
|         it('should revert if the hash of the output is different than expected expected', async () => { | ||||
|             const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(0)); | ||||
|             const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); | ||||
|             const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             await expectTransactionFailedAsync( | ||||
|                 staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount), | ||||
|                 RevertReason.UnexpectedStaticCallResult, | ||||
|             ); | ||||
|         }); | ||||
|         it('should be successful if a function call with no inputs and no outputs is successful', async () => { | ||||
|             const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData(); | ||||
|             const expectedResultHash = constants.KECCAK256_NULL; | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); | ||||
|         }); | ||||
|         it('should be successful if the staticCallTarget is not a contract and no return value is expected', async () => { | ||||
|             const staticCallData = '0x0102030405060708'; | ||||
|             const expectedResultHash = constants.KECCAK256_NULL; | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData(toAddress, staticCallData, expectedResultHash); | ||||
|             await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); | ||||
|         }); | ||||
|         it('should be successful if a function call with one static input returns the correct value', async () => { | ||||
|             const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(1)); | ||||
|             const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); | ||||
|             const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); | ||||
|         }); | ||||
|         it('should be successful if a function with one dynamic input is successful', async () => { | ||||
|             const dynamicInput = '0x0102030405060708'; | ||||
|             const staticCallData = staticCallTarget.dynamicInputFunction.getABIEncodedTransactionData(dynamicInput); | ||||
|             const expectedResultHash = constants.KECCAK256_NULL; | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); | ||||
|         }); | ||||
|         it('should be successful if a function call returns a complex type', async () => { | ||||
|             const a = new BigNumber(1); | ||||
|             const b = new BigNumber(2); | ||||
|             const staticCallData = staticCallTarget.returnComplexType.getABIEncodedTransactionData(a, b); | ||||
|             const abiEncoder = new AbiEncoder.DynamicBytes({ | ||||
|                 name: '', | ||||
|                 type: 'bytes', | ||||
|             }); | ||||
|             const aHex = '0000000000000000000000000000000000000000000000000000000000000001'; | ||||
|             const bHex = '0000000000000000000000000000000000000000000000000000000000000002'; | ||||
|             const expectedResults = `${staticCallTarget.address}${aHex}${bHex}`; | ||||
|             const offset = '0000000000000000000000000000000000000000000000000000000000000020'; | ||||
|             const encodedExpectedResultWithOffset = `0x${offset}${abiEncoder.encode(expectedResults).slice(2)}`; | ||||
|             const expectedResultHash = ethUtil.bufferToHex( | ||||
|                 ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)), | ||||
|             ); | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -36,11 +36,7 @@ export class ERC1155ProxyWrapper { | ||||
|         const allArtifacts = _.merge(artifacts, erc1155Artifacts); | ||||
|         this._logDecoder = new LogDecoder(this._web3Wrapper, allArtifacts); | ||||
|         this._dummyTokenWrappers = []; | ||||
|         this._assetProxyInterface = new IAssetProxyContract( | ||||
|             artifacts.IAssetProxy.compilerOutput.abi, | ||||
|             constants.NULL_ADDRESS, | ||||
|             provider, | ||||
|         ); | ||||
|         this._assetProxyInterface = new IAssetProxyContract(constants.NULL_ADDRESS, provider); | ||||
|         this._tokenOwnerAddresses = tokenOwnerAddresses; | ||||
|         this._contractOwnerAddress = contractOwnerAddress; | ||||
|         this._fungibleTokenIds = []; | ||||
| @@ -58,6 +54,7 @@ export class ERC1155ProxyWrapper { | ||||
|                 erc1155Artifacts.ERC1155Mintable, | ||||
|                 this._provider, | ||||
|                 txDefaults, | ||||
|                 artifacts, | ||||
|             ); | ||||
|             const erc1155Wrapper = new Erc1155Wrapper(erc1155Contract, this._provider, this._contractOwnerAddress); | ||||
|             this._dummyTokenWrappers.push(erc1155Wrapper); | ||||
| @@ -73,6 +70,7 @@ export class ERC1155ProxyWrapper { | ||||
|             artifacts.ERC1155Proxy, | ||||
|             this._provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync(); | ||||
|         return this._proxyContract; | ||||
| @@ -84,6 +82,66 @@ export class ERC1155ProxyWrapper { | ||||
|         this._validateProxyContractExistsOrThrow(); | ||||
|         return this._proxyIdIfExists as string; | ||||
|     } | ||||
|     /** | ||||
|      * @dev generates abi-encoded tx data for transferring erc1155 fungible/non-fungible tokens. | ||||
|      * @param from source address | ||||
|      * @param to destination address | ||||
|      * @param contractAddress address of erc155 contract | ||||
|      * @param tokensToTransfer array of erc1155 tokens to transfer | ||||
|      * @param valuesToTransfer array of corresponding values for each erc1155 token to transfer | ||||
|      * @param valueMultiplier each value in `valuesToTransfer` is multiplied by this | ||||
|      * @param receiverCallbackData callback data if `to` is a contract | ||||
|      * @param authorizedSender sender of `transferFrom` transaction | ||||
|      * @param extraData extra data to append to `transferFrom` transaction. Optional. | ||||
|      * @return abi encoded tx data. | ||||
|      */ | ||||
|     public getTransferFromAbiEncodedTxData( | ||||
|         from: string, | ||||
|         to: string, | ||||
|         contractAddress: string, | ||||
|         tokensToTransfer: BigNumber[], | ||||
|         valuesToTransfer: BigNumber[], | ||||
|         valueMultiplier: BigNumber, | ||||
|         receiverCallbackData: string, | ||||
|         authorizedSender: string, | ||||
|         assetData_?: string, | ||||
|     ): string { | ||||
|         this._validateProxyContractExistsOrThrow(); | ||||
|         const assetData = | ||||
|             assetData_ === undefined | ||||
|                 ? assetDataUtils.encodeERC1155AssetData( | ||||
|                       contractAddress, | ||||
|                       tokensToTransfer, | ||||
|                       valuesToTransfer, | ||||
|                       receiverCallbackData, | ||||
|                   ) | ||||
|                 : assetData_; | ||||
|         const data = this._assetProxyInterface.transferFrom.getABIEncodedTransactionData( | ||||
|             assetData, | ||||
|             from, | ||||
|             to, | ||||
|             valueMultiplier, | ||||
|         ); | ||||
|         return data; | ||||
|     } | ||||
|     /** | ||||
|      * @dev transfers erc1155 fungible/non-fungible tokens. | ||||
|      * @param txData: abi-encoded tx data | ||||
|      * @param authorizedSender sender of `transferFrom` transaction | ||||
|      */ | ||||
|     public async transferFromRawAsync( | ||||
|         txData: string, | ||||
|         authorizedSender: string, | ||||
|     ): Promise<TransactionReceiptWithDecodedLogs> { | ||||
|         const txHash = await this._web3Wrapper.sendTransactionAsync({ | ||||
|             to: (this._proxyContract as ERC1155ProxyContract).address, | ||||
|             data: txData, | ||||
|             from: authorizedSender, | ||||
|             gas: 300000, | ||||
|         }); | ||||
|         const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); | ||||
|         return txReceipt; | ||||
|     } | ||||
|     /** | ||||
|      * @dev transfers erc1155 fungible/non-fungible tokens. | ||||
|      * @param from source address | ||||
| @@ -106,20 +164,20 @@ export class ERC1155ProxyWrapper { | ||||
|         valueMultiplier: BigNumber, | ||||
|         receiverCallbackData: string, | ||||
|         authorizedSender: string, | ||||
|         extraData?: string, | ||||
|     ): Promise<string> { | ||||
|         assetData_?: string, | ||||
|     ): Promise<TransactionReceiptWithDecodedLogs> { | ||||
|         this._validateProxyContractExistsOrThrow(); | ||||
|         let encodedAssetData = assetDataUtils.encodeERC1155AssetData( | ||||
|             contractAddress, | ||||
|             tokensToTransfer, | ||||
|             valuesToTransfer, | ||||
|             receiverCallbackData, | ||||
|         ); | ||||
|         if (extraData !== undefined) { | ||||
|             encodedAssetData = `${encodedAssetData}${extraData}`; | ||||
|         } | ||||
|         const assetData = | ||||
|             assetData_ === undefined | ||||
|                 ? assetDataUtils.encodeERC1155AssetData( | ||||
|                       contractAddress, | ||||
|                       tokensToTransfer, | ||||
|                       valuesToTransfer, | ||||
|                       receiverCallbackData, | ||||
|                   ) | ||||
|                 : assetData_; | ||||
|         const data = this._assetProxyInterface.transferFrom.getABIEncodedTransactionData( | ||||
|             encodedAssetData, | ||||
|             assetData, | ||||
|             from, | ||||
|             to, | ||||
|             valueMultiplier, | ||||
| @@ -128,46 +186,9 @@ export class ERC1155ProxyWrapper { | ||||
|             to: (this._proxyContract as ERC1155ProxyContract).address, | ||||
|             data, | ||||
|             from: authorizedSender, | ||||
|             gas: 300000, | ||||
|         }); | ||||
|         return txHash; | ||||
|     } | ||||
|     /** | ||||
|      * @dev transfers erc1155 fungible/non-fungible tokens. | ||||
|      * @param from source address | ||||
|      * @param to destination address | ||||
|      * @param contractAddress address of erc155 contract | ||||
|      * @param tokensToTransfer array of erc1155 tokens to transfer | ||||
|      * @param valuesToTransfer array of corresponding values for each erc1155 token to transfer | ||||
|      * @param valueMultiplier each value in `valuesToTransfer` is multiplied by this | ||||
|      * @param receiverCallbackData callback data if `to` is a contract | ||||
|      * @param authorizedSender sender of `transferFrom` transaction | ||||
|      * @param extraData extra data to append to `transferFrom` transaction. Optional. | ||||
|      * @return tranasction receipt with decoded logs. | ||||
|      */ | ||||
|     public async transferFromWithLogsAsync( | ||||
|         from: string, | ||||
|         to: string, | ||||
|         contractAddress: string, | ||||
|         tokensToTransfer: BigNumber[], | ||||
|         valuesToTransfer: BigNumber[], | ||||
|         valueMultiplier: BigNumber, | ||||
|         receiverCallbackData: string, | ||||
|         authorizedSender: string, | ||||
|         extraData?: string, | ||||
|     ): Promise<TransactionReceiptWithDecodedLogs> { | ||||
|         const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync( | ||||
|             await this.transferFromAsync( | ||||
|                 from, | ||||
|                 to, | ||||
|                 contractAddress, | ||||
|                 tokensToTransfer, | ||||
|                 valuesToTransfer, | ||||
|                 valueMultiplier, | ||||
|                 receiverCallbackData, | ||||
|                 authorizedSender, | ||||
|                 extraData, | ||||
|             ), | ||||
|         ); | ||||
|         const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); | ||||
|         return txReceipt; | ||||
|     } | ||||
|     /** | ||||
|   | ||||
| @@ -2,7 +2,6 @@ import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contra | ||||
| import { constants, ERC20BalancesByOwner, txDefaults } from '@0x/contracts-test-utils'; | ||||
| import { assetDataUtils } from '@0x/order-utils'; | ||||
| import { BigNumber } from '@0x/utils'; | ||||
| import { Web3Wrapper } from '@0x/web3-wrapper'; | ||||
| import { ZeroExProvider } from 'ethereum-types'; | ||||
| import * as _ from 'lodash'; | ||||
|  | ||||
| @@ -11,7 +10,6 @@ import { artifacts, ERC20ProxyContract } from '../../src'; | ||||
| export class ERC20Wrapper { | ||||
|     private readonly _tokenOwnerAddresses: string[]; | ||||
|     private readonly _contractOwnerAddress: string; | ||||
|     private readonly _web3Wrapper: Web3Wrapper; | ||||
|     private readonly _provider: ZeroExProvider; | ||||
|     private readonly _dummyTokenContracts: DummyERC20TokenContract[]; | ||||
|     private _proxyContract?: ERC20ProxyContract; | ||||
| @@ -25,7 +23,6 @@ export class ERC20Wrapper { | ||||
|      */ | ||||
|     constructor(provider: ZeroExProvider, tokenOwnerAddresses: string[], contractOwnerAddress: string) { | ||||
|         this._dummyTokenContracts = []; | ||||
|         this._web3Wrapper = new Web3Wrapper(provider); | ||||
|         this._provider = provider; | ||||
|         this._tokenOwnerAddresses = tokenOwnerAddresses; | ||||
|         this._contractOwnerAddress = contractOwnerAddress; | ||||
| @@ -40,6 +37,7 @@ export class ERC20Wrapper { | ||||
|                     erc20Artifacts.DummyERC20Token, | ||||
|                     this._provider, | ||||
|                     txDefaults, | ||||
|                     artifacts, | ||||
|                     constants.DUMMY_TOKEN_NAME, | ||||
|                     constants.DUMMY_TOKEN_SYMBOL, | ||||
|                     decimals, | ||||
| @@ -54,6 +52,7 @@ export class ERC20Wrapper { | ||||
|             artifacts.ERC20Proxy, | ||||
|             this._provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync(); | ||||
|         return this._proxyContract; | ||||
| @@ -67,20 +66,16 @@ export class ERC20Wrapper { | ||||
|         this._validateProxyContractExistsOrThrow(); | ||||
|         for (const dummyTokenContract of this._dummyTokenContracts) { | ||||
|             for (const tokenOwnerAddress of this._tokenOwnerAddresses) { | ||||
|                 await this._web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                     await dummyTokenContract.setBalance.sendTransactionAsync( | ||||
|                         tokenOwnerAddress, | ||||
|                         constants.INITIAL_ERC20_BALANCE, | ||||
|                         { from: this._contractOwnerAddress }, | ||||
|                     ), | ||||
|                 await dummyTokenContract.setBalance.awaitTransactionSuccessAsync( | ||||
|                     tokenOwnerAddress, | ||||
|                     constants.INITIAL_ERC20_BALANCE, | ||||
|                     { from: this._contractOwnerAddress }, | ||||
|                     constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|                 ); | ||||
|                 await this._web3Wrapper.awaitTransactionSuccessAsync( | ||||
|                     await dummyTokenContract.approve.sendTransactionAsync( | ||||
|                         (this._proxyContract as ERC20ProxyContract).address, | ||||
|                         constants.INITIAL_ERC20_ALLOWANCE, | ||||
|                         { from: tokenOwnerAddress }, | ||||
|                     ), | ||||
|                 await dummyTokenContract.approve.awaitTransactionSuccessAsync( | ||||
|                     (this._proxyContract as ERC20ProxyContract).address, | ||||
|                     constants.INITIAL_ERC20_ALLOWANCE, | ||||
|                     { from: tokenOwnerAddress }, | ||||
|                     constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|                 ); | ||||
|             } | ||||
| @@ -93,10 +88,10 @@ export class ERC20Wrapper { | ||||
|     } | ||||
|     public async setBalanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> { | ||||
|         const tokenContract = this._getTokenContractFromAssetData(assetData); | ||||
|         await this._web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await tokenContract.setBalance.sendTransactionAsync(userAddress, amount, { | ||||
|                 from: this._contractOwnerAddress, | ||||
|             }), | ||||
|         await tokenContract.setBalance.awaitTransactionSuccessAsync( | ||||
|             userAddress, | ||||
|             amount, | ||||
|             { from: this._contractOwnerAddress }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|     } | ||||
| @@ -109,10 +104,10 @@ export class ERC20Wrapper { | ||||
|     public async setAllowanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> { | ||||
|         const tokenContract = this._getTokenContractFromAssetData(assetData); | ||||
|         const proxyAddress = (this._proxyContract as ERC20ProxyContract).address; | ||||
|         await this._web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await tokenContract.approve.sendTransactionAsync(proxyAddress, amount, { | ||||
|                 from: userAddress, | ||||
|             }), | ||||
|         await tokenContract.approve.awaitTransactionSuccessAsync( | ||||
|             proxyAddress, | ||||
|             amount, | ||||
|             { from: userAddress }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|     } | ||||
|   | ||||
| @@ -2,7 +2,6 @@ import { artifacts as erc721Artifacts, DummyERC721TokenContract } from '@0x/cont | ||||
| import { constants, ERC721TokenIdsByOwner, txDefaults } from '@0x/contracts-test-utils'; | ||||
| import { generatePseudoRandomSalt } from '@0x/order-utils'; | ||||
| import { BigNumber } from '@0x/utils'; | ||||
| import { Web3Wrapper } from '@0x/web3-wrapper'; | ||||
| import { ZeroExProvider } from 'ethereum-types'; | ||||
| import * as _ from 'lodash'; | ||||
|  | ||||
| @@ -11,14 +10,12 @@ import { artifacts, ERC721ProxyContract } from '../../src'; | ||||
| export class ERC721Wrapper { | ||||
|     private readonly _tokenOwnerAddresses: string[]; | ||||
|     private readonly _contractOwnerAddress: string; | ||||
|     private readonly _web3Wrapper: Web3Wrapper; | ||||
|     private readonly _provider: ZeroExProvider; | ||||
|     private readonly _dummyTokenContracts: DummyERC721TokenContract[]; | ||||
|     private _proxyContract?: ERC721ProxyContract; | ||||
|     private _proxyIdIfExists?: string; | ||||
|     private _initialTokenIdsByOwner: ERC721TokenIdsByOwner = {}; | ||||
|     constructor(provider: ZeroExProvider, tokenOwnerAddresses: string[], contractOwnerAddress: string) { | ||||
|         this._web3Wrapper = new Web3Wrapper(provider); | ||||
|         this._provider = provider; | ||||
|         this._dummyTokenContracts = []; | ||||
|         this._tokenOwnerAddresses = tokenOwnerAddresses; | ||||
| @@ -32,6 +29,7 @@ export class ERC721Wrapper { | ||||
|                     erc721Artifacts.DummyERC721Token, | ||||
|                     this._provider, | ||||
|                     txDefaults, | ||||
|                     artifacts, | ||||
|                     constants.DUMMY_TOKEN_NAME, | ||||
|                     constants.DUMMY_TOKEN_SYMBOL, | ||||
|                 ), | ||||
| @@ -44,6 +42,7 @@ export class ERC721Wrapper { | ||||
|             artifacts.ERC721Proxy, | ||||
|             this._provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync(); | ||||
|         return this._proxyContract; | ||||
| @@ -91,20 +90,20 @@ export class ERC721Wrapper { | ||||
|         const tokenContract = this._getTokenContractFromAssetData(tokenAddress); | ||||
|         const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId); | ||||
|         const proxyAddress = (this._proxyContract as ERC721ProxyContract).address; | ||||
|         await this._web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await tokenContract.setApprovalForAll.sendTransactionAsync(proxyAddress, isApproved, { | ||||
|                 from: tokenOwner, | ||||
|             }), | ||||
|         await tokenContract.setApprovalForAll.awaitTransactionSuccessAsync( | ||||
|             proxyAddress, | ||||
|             isApproved, | ||||
|             { from: tokenOwner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|     } | ||||
|     public async approveAsync(to: string, tokenAddress: string, tokenId: BigNumber): Promise<void> { | ||||
|         const tokenContract = this._getTokenContractFromAssetData(tokenAddress); | ||||
|         const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId); | ||||
|         await this._web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await tokenContract.approve.sendTransactionAsync(to, tokenId, { | ||||
|                 from: tokenOwner, | ||||
|             }), | ||||
|         await tokenContract.approve.awaitTransactionSuccessAsync( | ||||
|             to, | ||||
|             tokenId, | ||||
|             { from: tokenOwner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|     } | ||||
| @@ -115,28 +114,29 @@ export class ERC721Wrapper { | ||||
|         userAddress: string, | ||||
|     ): Promise<void> { | ||||
|         const tokenContract = this._getTokenContractFromAssetData(tokenAddress); | ||||
|         await this._web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await tokenContract.transferFrom.sendTransactionAsync(currentOwner, userAddress, tokenId, { | ||||
|                 from: currentOwner, | ||||
|             }), | ||||
|         await tokenContract.transferFrom.awaitTransactionSuccessAsync( | ||||
|             currentOwner, | ||||
|             userAddress, | ||||
|             tokenId, | ||||
|             { from: currentOwner }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|     } | ||||
|     public async mintAsync(tokenAddress: string, tokenId: BigNumber, userAddress: string): Promise<void> { | ||||
|         const tokenContract = this._getTokenContractFromAssetData(tokenAddress); | ||||
|         await this._web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await tokenContract.mint.sendTransactionAsync(userAddress, tokenId, { | ||||
|                 from: this._contractOwnerAddress, | ||||
|             }), | ||||
|         await tokenContract.mint.awaitTransactionSuccessAsync( | ||||
|             userAddress, | ||||
|             tokenId, | ||||
|             { from: this._contractOwnerAddress }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|     } | ||||
|     public async burnAsync(tokenAddress: string, tokenId: BigNumber, owner: string): Promise<void> { | ||||
|         const tokenContract = this._getTokenContractFromAssetData(tokenAddress); | ||||
|         await this._web3Wrapper.awaitTransactionSuccessAsync( | ||||
|             await tokenContract.burn.sendTransactionAsync(owner, tokenId, { | ||||
|                 from: this._contractOwnerAddress, | ||||
|             }), | ||||
|         await tokenContract.burn.awaitTransactionSuccessAsync( | ||||
|             owner, | ||||
|             tokenId, | ||||
|             { from: this._contractOwnerAddress }, | ||||
|             constants.AWAIT_TRANSACTION_MINED_MS, | ||||
|         ); | ||||
|     } | ||||
|   | ||||
| @@ -10,7 +10,9 @@ | ||||
|         "generated-artifacts/IAssetProxy.json", | ||||
|         "generated-artifacts/IAuthorizable.json", | ||||
|         "generated-artifacts/MixinAuthorizable.json", | ||||
|         "generated-artifacts/MultiAssetProxy.json" | ||||
|         "generated-artifacts/MultiAssetProxy.json", | ||||
|         "generated-artifacts/StaticCallProxy.json", | ||||
|         "generated-artifacts/TestStaticCallTarget.json" | ||||
|     ], | ||||
|     "exclude": ["./deploy/solc/solc_bin"] | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,95 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1565296576, | ||||
|         "version": "2.0.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.0.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies.", | ||||
|                 "pr": 1995 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1564607468 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563957393, | ||||
|         "version": "2.0.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563193019, | ||||
|         "version": "2.0.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563047529, | ||||
|         "version": "2.0.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563006338, | ||||
|         "version": "2.0.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1558712885, | ||||
|         "version": "2.0.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557961111, | ||||
|         "version": "2.0.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557799313, | ||||
|         "version": "2.0.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557507213, | ||||
|         "version": "2.0.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.0.0", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,46 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v2.0.10 - _August 8, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.9 - _July 31, 2019_ | ||||
|  | ||||
|     * Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies. (#1995) | ||||
|  | ||||
| ## v2.0.8 - _July 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.7 - _July 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.6 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.5 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.4 - _May 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.3 - _May 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.2 - _May 14, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.1 - _May 10, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.0 - _April 11, 2019_ | ||||
|  | ||||
|     * Make `decodeOrdersFromFillData`, `getCoordinatorApprovalHash`, and `getTransactionHash` public (#1729) | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|     "artifactsDir": "./generated-artifacts", | ||||
|     "contractsDir": "./contracts", | ||||
|     "useDockerisedSolc": true, | ||||
|     "useDockerisedSolc": false, | ||||
|     "compilerSettings": { | ||||
|         "evmVersion": "constantinople", | ||||
|         "optimizer": { | ||||
| @@ -13,6 +13,7 @@ | ||||
|             "*": { | ||||
|                 "*": [ | ||||
|                     "abi", | ||||
|                     "devdoc", | ||||
|                     "evm.bytecode.object", | ||||
|                     "evm.bytecode.sourceMap", | ||||
|                     "evm.deployedBytecode.object", | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-coordinator", | ||||
|     "version": "2.0.0", | ||||
|     "version": "2.0.10", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -47,20 +47,21 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^2.0.9", | ||||
|         "@0x/contracts-gen": "^1.0.8", | ||||
|         "@0x/contracts-test-utils": "^3.1.2", | ||||
|         "@0x/dev-utils": "^2.2.1", | ||||
|         "@0x/sol-compiler": "^3.1.6", | ||||
|         "@0x/abi-gen": "^4.1.0", | ||||
|         "@0x/contracts-gen": "^1.0.13", | ||||
|         "@0x/contracts-test-utils": "^3.1.13", | ||||
|         "@0x/dev-utils": "^2.3.0", | ||||
|         "@0x/sol-compiler": "^3.1.12", | ||||
|         "@0x/tslint-config": "^3.0.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^4.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
|         "solhint": "^1.4.1", | ||||
| @@ -68,18 +69,18 @@ | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^5.0.5", | ||||
|         "@0x/contracts-asset-proxy": "^2.1.1", | ||||
|         "@0x/contracts-erc20": "^2.2.0", | ||||
|         "@0x/contracts-exchange": "1.0.2", | ||||
|         "@0x/contracts-exchange-libs": "^2.1.1", | ||||
|         "@0x/contracts-utils": "^3.1.1", | ||||
|         "@0x/order-utils": "^7.2.0", | ||||
|         "@0x/types": "^2.2.2", | ||||
|         "@0x/typescript-typings": "^4.2.2", | ||||
|         "@0x/utils": "^4.3.1", | ||||
|         "@0x/web3-wrapper": "^6.0.5", | ||||
|         "ethereum-types": "^2.1.2", | ||||
|         "@0x/base-contract": "^5.3.1", | ||||
|         "@0x/contracts-asset-proxy": "^2.2.5", | ||||
|         "@0x/contracts-erc20": "^2.2.11", | ||||
|         "@0x/contracts-exchange": "^2.1.11", | ||||
|         "@0x/contracts-exchange-libs": "^3.0.5", | ||||
|         "@0x/contracts-utils": "^3.2.1", | ||||
|         "@0x/order-utils": "^8.2.5", | ||||
|         "@0x/types": "^2.4.1", | ||||
|         "@0x/typescript-typings": "^4.2.4", | ||||
|         "@0x/utils": "^4.5.0", | ||||
|         "@0x/web3-wrapper": "^6.0.10", | ||||
|         "ethereum-types": "^2.1.4", | ||||
|         "ethereumjs-util": "^5.1.1", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|   | ||||
| @@ -74,6 +74,7 @@ describe('Coordinator tests', () => { | ||||
|             exchangeArtifacts.Exchange, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             assetDataUtils.encodeERC20AssetData(zrxToken.address), | ||||
|         ); | ||||
|  | ||||
| @@ -91,6 +92,7 @@ describe('Coordinator tests', () => { | ||||
|             artifacts.Coordinator, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             exchange.address, | ||||
|         ); | ||||
|  | ||||
|   | ||||
| @@ -25,6 +25,7 @@ describe('Libs tests', () => { | ||||
|             artifacts.Coordinator, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             exchangeAddress, | ||||
|         ); | ||||
|     }); | ||||
|   | ||||
| @@ -44,6 +44,7 @@ describe('Mixins tests', () => { | ||||
|             artifacts.Coordinator, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             exchangeAddress, | ||||
|         ); | ||||
|         const accounts = await web3Wrapper.getAvailableAddressesAsync(); | ||||
|   | ||||
| @@ -24,6 +24,7 @@ export class CoordinatorRegistryWrapper { | ||||
|             artifacts.CoordinatorRegistry, | ||||
|             this._provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         if (this._coordinatorRegistryContract === undefined) { | ||||
|             throw new Error(`Failed to deploy Coordinator Registry contract.`); | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { artifacts, IExchangeContract } from '@0x/contracts-exchange'; | ||||
| import { IExchangeContract } from '@0x/contracts-exchange'; | ||||
| import { constants as devConstants, provider } from '@0x/contracts-test-utils'; | ||||
| import { SignedOrder } from '@0x/types'; | ||||
|  | ||||
| @@ -6,11 +6,7 @@ import { constants } from './index'; | ||||
|  | ||||
| export const exchangeDataEncoder = { | ||||
|     encodeOrdersToExchangeData(fnName: string, orders: SignedOrder[]): string { | ||||
|         const exchangeInstance = new IExchangeContract( | ||||
|             artifacts.IExchange.compilerOutput.abi, | ||||
|             devConstants.NULL_ADDRESS, | ||||
|             provider, | ||||
|         ); | ||||
|         const exchangeInstance = new IExchangeContract(devConstants.NULL_ADDRESS, provider); | ||||
|         let data; | ||||
|         if (constants.SINGLE_FILL_FN_NAMES.indexOf(fnName) !== -1) { | ||||
|             data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData( | ||||
|   | ||||
							
								
								
									
										95
									
								
								contracts/dev-utils/CHANGELOG.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								contracts/dev-utils/CHANGELOG.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1565296576, | ||||
|         "version": "0.0.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1564607468, | ||||
|         "version": "0.0.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "0.0.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies.", | ||||
|                 "pr": 1995 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1564604963 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563957393, | ||||
|         "version": "0.0.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563193019, | ||||
|         "version": "0.0.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563047529, | ||||
|         "version": "0.0.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563006338, | ||||
|         "version": "0.0.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "0.0.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Create dev-utils package", | ||||
|                 "pr": 1848 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add `LibAssetData` and `LibTransactionDecoder` contracts", | ||||
|                 "pr": 1848 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Refactor `LibAssetData` to only check 0x-specific allowances", | ||||
|                 "pr": 1848 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Refactor `LibAssetData` balance/allowance checks to never revert", | ||||
|                 "pr": 1848 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Refactor `OrderValidationUtils` to calculate `fillableTakerAssetAmount`", | ||||
|                 "pr": 1848 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add support for StaticCallProxy", | ||||
|                 "pr": 1863 | ||||
|             } | ||||
|         ] | ||||
|     } | ||||
| ] | ||||
							
								
								
									
										43
									
								
								contracts/dev-utils/CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								contracts/dev-utils/CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| <!-- | ||||
| changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly. | ||||
| Edit the package's CHANGELOG.json file only. | ||||
| --> | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v0.0.7 - _August 8, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.0.6 - _July 31, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.0.5 - _July 31, 2019_ | ||||
|  | ||||
|     * Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies. (#1995) | ||||
|  | ||||
| ## v0.0.5 - _July 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.0.4 - _July 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.0.3 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.0.2 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.0.1 - _Invalid date_ | ||||
|  | ||||
|     * Create dev-utils package (#1848) | ||||
|     * Add `LibAssetData` and `LibTransactionDecoder` contracts (#1848) | ||||
|     * Refactor `LibAssetData` to only check 0x-specific allowances (#1848) | ||||
|     * Refactor `LibAssetData` balance/allowance checks to never revert (#1848) | ||||
|     * Refactor `OrderValidationUtils` to calculate `fillableTakerAssetAmount` (#1848) | ||||
|     * Add support for StaticCallProxy (#1863) | ||||
							
								
								
									
										1
									
								
								contracts/dev-utils/DEPLOYS.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								contracts/dev-utils/DEPLOYS.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| [] | ||||
							
								
								
									
										73
									
								
								contracts/dev-utils/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								contracts/dev-utils/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| ## Dev-Utils | ||||
|  | ||||
| This package implements various utilities for developers. For example, the `DevUtils` contract can query batches of balances or allowances given some `assetData`, can validate batches of orders, and can decode 0x-specific calldata. Addresses of the deployed contracts can be found in the 0x [wiki](https://0xproject.com/wiki#Deployed-Addresses) or the [DEPLOYS](./DEPLOYS.json) file within this package. | ||||
|  | ||||
| ## Installation | ||||
|  | ||||
| **Install** | ||||
|  | ||||
| ```bash | ||||
| npm install @0x/contracts-dev-utils --save | ||||
| ``` | ||||
|  | ||||
| ## Bug bounty | ||||
|  | ||||
| A bug bounty for the 2.0.0 contracts is ongoing! Instructions can be found [here](https://0xproject.com/wiki#Bug-Bounty). | ||||
|  | ||||
| ## Contributing | ||||
|  | ||||
| We strongly recommend that the community help us make improvements and determine the future direction of the protocol. To report bugs within this package, please create an issue in this repository. | ||||
|  | ||||
| For proposals regarding the 0x protocol's smart contract architecture, message format, or additional functionality, go to the [0x Improvement Proposals (ZEIPs)](https://github.com/0xProject/ZEIPs) repository and follow the contribution guidelines provided therein. | ||||
|  | ||||
| Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started. | ||||
|  | ||||
| ### Install Dependencies | ||||
|  | ||||
| If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them: | ||||
|  | ||||
| ```bash | ||||
| yarn config set workspaces-experimental true | ||||
| ``` | ||||
|  | ||||
| Then install dependencies | ||||
|  | ||||
| ```bash | ||||
| yarn install | ||||
| ``` | ||||
|  | ||||
| ### Build | ||||
|  | ||||
| To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory: | ||||
|  | ||||
| ```bash | ||||
| PKG=@0x/contracts-extensions yarn build | ||||
| ``` | ||||
|  | ||||
| Or continuously rebuild on change: | ||||
|  | ||||
| ```bash | ||||
| PKG=@0x/contracts-extensions yarn watch | ||||
| ``` | ||||
|  | ||||
| ### Clean | ||||
|  | ||||
| ```bash | ||||
| yarn clean | ||||
| ``` | ||||
|  | ||||
| ### Lint | ||||
|  | ||||
| ```bash | ||||
| yarn lint | ||||
| ``` | ||||
|  | ||||
| ### Run Tests | ||||
|  | ||||
| ```bash | ||||
| yarn test | ||||
| ``` | ||||
|  | ||||
| #### Testing options | ||||
|  | ||||
| Contracts testing options like coverage, profiling, revert traces or backing node choosing - are described [here](../TESTING.md). | ||||
							
								
								
									
										32
									
								
								contracts/dev-utils/compiler.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								contracts/dev-utils/compiler.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| { | ||||
|     "artifactsDir": "./generated-artifacts", | ||||
|     "contractsDir": "./contracts", | ||||
|     "useDockerisedSolc": false, | ||||
|     "isOfflineMode": false, | ||||
|     "compilerSettings": { | ||||
|         "evmVersion": "constantinople", | ||||
|         "optimizer": { | ||||
|             "enabled": true, | ||||
|             "runs": 1000000, | ||||
|             "details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true } | ||||
|         }, | ||||
|         "outputSelection": { | ||||
|             "*": { | ||||
|                 "*": [ | ||||
|                     "abi", | ||||
|                     "devdoc", | ||||
|                     "evm.bytecode.object", | ||||
|                     "evm.bytecode.sourceMap", | ||||
|                     "evm.deployedBytecode.object", | ||||
|                     "evm.deployedBytecode.sourceMap" | ||||
|                 ] | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "contracts": [ | ||||
|         "src/DevUtils.sol", | ||||
|         "src/LibAssetData.sol", | ||||
|         "src/LibTransactionDecoder.sol", | ||||
|         "src/EthBalanceChecker.sol" | ||||
|     ] | ||||
| } | ||||
							
								
								
									
										37
									
								
								contracts/dev-utils/contracts/src/DevUtils.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								contracts/dev-utils/contracts/src/DevUtils.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| /* | ||||
|  | ||||
|   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.5.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "./OrderValidationUtils.sol"; | ||||
| import "./LibTransactionDecoder.sol"; | ||||
| import "./EthBalanceChecker.sol"; | ||||
|  | ||||
|  | ||||
| // solhint-disable no-empty-blocks | ||||
| contract DevUtils is | ||||
|     OrderValidationUtils, | ||||
|     LibTransactionDecoder, | ||||
|     EthBalanceChecker | ||||
| { | ||||
|     constructor (address _exchange, bytes memory _zrxAssetData) | ||||
|         public | ||||
|         OrderValidationUtils(_exchange, _zrxAssetData) | ||||
|     {} | ||||
| } | ||||
							
								
								
									
										39
									
								
								contracts/dev-utils/contracts/src/EthBalanceChecker.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								contracts/dev-utils/contracts/src/EthBalanceChecker.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| /* | ||||
|  | ||||
|   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.5.5; | ||||
|  | ||||
|  | ||||
| contract EthBalanceChecker { | ||||
|  | ||||
|     /// @dev Batch fetches ETH balances | ||||
|     /// @param addresses Array of addresses. | ||||
|     /// @return Array of ETH balances. | ||||
|     function getEthBalances(address[] memory addresses) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory) | ||||
|     { | ||||
|         uint256[] memory balances = new uint256[](addresses.length); | ||||
|         for (uint256 i = 0; i != addresses.length; i++) { | ||||
|             balances[i] = addresses[i].balance; | ||||
|         } | ||||
|         return balances; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										541
									
								
								contracts/dev-utils/contracts/src/LibAssetData.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										541
									
								
								contracts/dev-utils/contracts/src/LibAssetData.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,541 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2019 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.5.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-utils/contracts/src/LibBytes.sol"; | ||||
| import "@0x/contracts-asset-proxy/contracts/src/libs/LibAssetProxyIds.sol"; | ||||
| import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol"; | ||||
|  | ||||
|  | ||||
| contract LibAssetData is | ||||
|     LibAssetProxyIds | ||||
| { | ||||
|     // 2^256 - 1 | ||||
|     uint256 constant internal _MAX_UINT256 = uint256(-1); | ||||
|  | ||||
|     // ERC20 selectors | ||||
|     bytes4 constant internal _ERC20_BALANCE_OF_SELECTOR = 0x70a08231; | ||||
|     bytes4 constant internal _ERC20_ALLOWANCE_SELECTOR = 0xdd62ed3e; | ||||
|  | ||||
|     // ERC721 selectors | ||||
|     bytes4 constant internal _ERC721_OWNER_OF_SELECTOR = 0x6352211e; | ||||
|     bytes4 constant internal _ERC721_IS_APPROVED_FOR_ALL_SELECTOR = 0xe985e9c5; | ||||
|     bytes4 constant internal _ERC721_GET_APPROVED_SELECTOR = 0x081812fc; | ||||
|  | ||||
|     // ERC1155 selectors | ||||
|     bytes4 constant internal _ERC1155_BALANCE_OF_SELECTOR = 0x00fdd58e; | ||||
|     bytes4 constant internal _ERC1155_IS_APPROVED_FOR_ALL_SELECTOR = 0xe985e9c5; | ||||
|  | ||||
|     // `transferFrom` selector for all AssetProxy contracts | ||||
|     bytes4 constant internal _ASSET_PROXY_TRANSFER_FROM_SELECTOR = 0xa85e59e4; | ||||
|  | ||||
|     using LibBytes for bytes; | ||||
|  | ||||
|     // solhint-disable var-name-mixedcase | ||||
|     IExchange internal _EXCHANGE; | ||||
|     address internal _ERC20_PROXY_ADDRESS; | ||||
|     address internal _ERC721_PROXY_ADDRESS; | ||||
|     address internal _ERC1155_PROXY_ADDRESS; | ||||
|     address internal _STATIC_CALL_PROXY_ADDRESS; | ||||
|     // solhint-enable var-name-mixedcase | ||||
|  | ||||
|     constructor (address _exchange) | ||||
|         public | ||||
|     { | ||||
|         _EXCHANGE = IExchange(_exchange); | ||||
|         _ERC20_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(ERC20_PROXY_ID); | ||||
|         _ERC721_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(ERC721_PROXY_ID); | ||||
|         _ERC1155_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(ERC1155_PROXY_ID); | ||||
|         _STATIC_CALL_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(STATIC_CALL_PROXY_ID); | ||||
|     } | ||||
|  | ||||
|     /// @dev Returns the owner's balance of the assets(s) specified in | ||||
|     /// assetData.  When the asset data contains multiple assets (eg in | ||||
|     /// ERC1155 or Multi-Asset), the return value indicates how many | ||||
|     /// complete "baskets" of those assets are owned by owner. | ||||
|     /// @param ownerAddress Owner of the assets specified by assetData. | ||||
|     /// @param assetData Details of asset, encoded per the AssetProxy contract specification. | ||||
|     /// @return Number of assets (or asset baskets) held by owner. | ||||
|     function getBalance(address ownerAddress, bytes memory assetData) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256 balance) | ||||
|     { | ||||
|         // Get id of AssetProxy contract | ||||
|         bytes4 assetProxyId = assetData.readBytes4(0); | ||||
|  | ||||
|         if (assetProxyId == ERC20_PROXY_ID) { | ||||
|             // Get ERC20 token address | ||||
|             address tokenAddress = assetData.readAddress(16); | ||||
|  | ||||
|             // Encode data for `balanceOf(ownerAddress)` | ||||
|             bytes memory balanceOfData = abi.encodeWithSelector(_ERC20_BALANCE_OF_SELECTOR, ownerAddress); | ||||
|  | ||||
|             // Query balance | ||||
|             (bool success, bytes memory returnData) = tokenAddress.staticcall(balanceOfData); | ||||
|             balance = success && returnData.length == 32 ? returnData.readUint256(0) : 0; | ||||
|         } else if (assetProxyId == ERC721_PROXY_ID) { | ||||
|             // Get ERC721 token address and id | ||||
|             (, address tokenAddress, uint256 tokenId) = decodeERC721AssetData(assetData); | ||||
|  | ||||
|             // Check if id is owned by ownerAddress | ||||
|             balance = getERC721TokenOwner(tokenAddress, tokenId) == ownerAddress ? 1 : 0; | ||||
|         } else if (assetProxyId == ERC1155_PROXY_ID) { | ||||
|             // Get ERC1155 token address, array of ids, and array of values | ||||
|             (, address tokenAddress, uint256[] memory tokenIds, uint256[] memory tokenValues,) = decodeERC1155AssetData(assetData); | ||||
|  | ||||
|             uint256 length = tokenIds.length; | ||||
|             for (uint256 i = 0; i != length; i++) { | ||||
|                 // Encode data for `balanceOf(ownerAddress, tokenIds[i]) | ||||
|                 bytes memory balanceOfData = abi.encodeWithSelector( | ||||
|                     _ERC1155_BALANCE_OF_SELECTOR, | ||||
|                     ownerAddress, | ||||
|                     tokenIds[i] | ||||
|                 ); | ||||
|  | ||||
|                 // Query balance | ||||
|                 (bool success, bytes memory returnData) = tokenAddress.staticcall(balanceOfData); | ||||
|                 uint256 totalBalance = success && returnData.length == 32 ? returnData.readUint256(0) : 0; | ||||
|  | ||||
|                 // Scale total balance down by corresponding value in assetData | ||||
|                 uint256 scaledBalance = totalBalance / tokenValues[i]; | ||||
|                 if (scaledBalance < balance || balance == 0) { | ||||
|                     balance = scaledBalance; | ||||
|                 } | ||||
|             } | ||||
|         } else if (assetProxyId == STATIC_CALL_PROXY_ID) { | ||||
|             // Encode data for `staticCallProxy.transferFrom(assetData,...)` | ||||
|             bytes memory transferFromData = abi.encodeWithSelector( | ||||
|                 _ASSET_PROXY_TRANSFER_FROM_SELECTOR, | ||||
|                 assetData, | ||||
|                 address(0),  // `from` address is not used | ||||
|                 address(0),  // `to` address is not used | ||||
|                 0            // `amount` is not used | ||||
|             ); | ||||
|  | ||||
|             // Check if staticcall would be successful | ||||
|             (bool success,) = _STATIC_CALL_PROXY_ADDRESS.staticcall(transferFromData); | ||||
|  | ||||
|             // Success means that the staticcall can be made an unlimited amount of times | ||||
|             balance = success ? _MAX_UINT256 : 0; | ||||
|         } else if (assetProxyId == MULTI_ASSET_PROXY_ID) { | ||||
|             // Get array of values and array of assetDatas | ||||
|             (, uint256[] memory assetAmounts, bytes[] memory nestedAssetData) = decodeMultiAssetData(assetData); | ||||
|  | ||||
|             uint256 length = nestedAssetData.length; | ||||
|             for (uint256 i = 0; i != length; i++) { | ||||
|                 // Query balance of individual assetData | ||||
|                 uint256 totalBalance = getBalance(ownerAddress, nestedAssetData[i]); | ||||
|  | ||||
|                 // Scale total balance down by corresponding value in assetData | ||||
|                 uint256 scaledBalance = totalBalance / assetAmounts[i]; | ||||
|                 if (scaledBalance < balance || balance == 0) { | ||||
|                     balance = scaledBalance; | ||||
|                 } | ||||
|             } | ||||
|         }  | ||||
|  | ||||
|         // Balance will be 0 if assetProxyId is unknown | ||||
|         return balance; | ||||
|     } | ||||
|  | ||||
|     /// @dev Calls getBalance() for each element of assetData. | ||||
|     /// @param ownerAddress Owner of the assets specified by assetData. | ||||
|     /// @param assetData Array of asset details, each encoded per the AssetProxy contract specification. | ||||
|     /// @return Array of asset balances from getBalance(), with each element | ||||
|     /// corresponding to the same-indexed element in the assetData input. | ||||
|     function getBatchBalances(address ownerAddress, bytes[] memory assetData) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory balances) | ||||
|     { | ||||
|         uint256 length = assetData.length; | ||||
|         balances = new uint256[](length); | ||||
|         for (uint256 i = 0; i != length; i++) { | ||||
|             balances[i] = getBalance(ownerAddress, assetData[i]); | ||||
|         } | ||||
|         return balances; | ||||
|     } | ||||
|  | ||||
|     /// @dev Returns the number of asset(s) (described by assetData) that | ||||
|     /// the corresponding AssetProxy contract is authorized to spend.  When the asset data contains | ||||
|     /// multiple assets (eg for Multi-Asset), the return value indicates | ||||
|     /// how many complete "baskets" of those assets may be spent by all of the corresponding | ||||
|     /// AssetProxy contracts. | ||||
|     /// @param ownerAddress Owner of the assets specified by assetData. | ||||
|     /// @param assetData Details of asset, encoded per the AssetProxy contract specification. | ||||
|     /// @return Number of assets (or asset baskets) that the corresponding AssetProxy is authorized to spend. | ||||
|     function getAssetProxyAllowance(address ownerAddress, bytes memory assetData) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256 allowance) | ||||
|     { | ||||
|         // Get id of AssetProxy contract | ||||
|         bytes4 assetProxyId = assetData.readBytes4(0); | ||||
|  | ||||
|         if (assetProxyId == MULTI_ASSET_PROXY_ID) { | ||||
|             // Get array of values and array of assetDatas | ||||
|             (, uint256[] memory amounts, bytes[] memory nestedAssetData) = decodeMultiAssetData(assetData); | ||||
|  | ||||
|             uint256 length = nestedAssetData.length; | ||||
|             for (uint256 i = 0; i != length; i++) { | ||||
|                 // Query allowance of individual assetData | ||||
|                 uint256 totalAllowance = getAssetProxyAllowance(ownerAddress, nestedAssetData[i]); | ||||
|  | ||||
|                 // Scale total allowance down by corresponding value in assetData | ||||
|                 uint256 scaledAllowance = totalAllowance / amounts[i]; | ||||
|                 if (scaledAllowance < allowance || allowance == 0) { | ||||
|                     allowance = scaledAllowance; | ||||
|                 } | ||||
|             } | ||||
|             return allowance; | ||||
|         } | ||||
|  | ||||
|         if (assetProxyId == ERC20_PROXY_ID) { | ||||
|             // Get ERC20 token address | ||||
|             address tokenAddress = assetData.readAddress(16); | ||||
|  | ||||
|             // Encode data for `allowance(ownerAddress, _ERC20_PROXY_ADDRESS)` | ||||
|             bytes memory allowanceData = abi.encodeWithSelector( | ||||
|                 _ERC20_ALLOWANCE_SELECTOR, | ||||
|                 ownerAddress, | ||||
|                 _ERC20_PROXY_ADDRESS | ||||
|             ); | ||||
|  | ||||
|             // Query allowance | ||||
|             (bool success, bytes memory returnData) = tokenAddress.staticcall(allowanceData); | ||||
|             allowance = success && returnData.length == 32 ? returnData.readUint256(0) : 0; | ||||
|         } else if (assetProxyId == ERC721_PROXY_ID) { | ||||
|             // Get ERC721 token address and id | ||||
|             (, address tokenAddress, uint256 tokenId) = decodeERC721AssetData(assetData); | ||||
|  | ||||
|             // Encode data for `isApprovedForAll(ownerAddress, _ERC721_PROXY_ADDRESS)` | ||||
|             bytes memory isApprovedForAllData = abi.encodeWithSelector( | ||||
|                 _ERC721_IS_APPROVED_FOR_ALL_SELECTOR, | ||||
|                 ownerAddress, | ||||
|                 _ERC721_PROXY_ADDRESS | ||||
|             ); | ||||
|  | ||||
|             (bool success, bytes memory returnData) = tokenAddress.staticcall(isApprovedForAllData); | ||||
|  | ||||
|             // If not approved for all, call `getApproved(tokenId)` | ||||
|             if (!success || returnData.length != 32 || returnData.readUint256(0) != 1) { | ||||
|                 // Encode data for `getApproved(tokenId)` | ||||
|                 bytes memory getApprovedData = abi.encodeWithSelector(_ERC721_GET_APPROVED_SELECTOR, tokenId); | ||||
|                 (success, returnData) = tokenAddress.staticcall(getApprovedData); | ||||
|  | ||||
|                 // Allowance is 1 if successful and the approved address is the ERC721Proxy | ||||
|                 allowance = success && returnData.length == 32 && returnData.readAddress(12) == _ERC721_PROXY_ADDRESS ? 1 : 0; | ||||
|             } else { | ||||
|                 // Allowance is 2^256 - 1 if `isApprovedForAll` returned true | ||||
|                 allowance = _MAX_UINT256; | ||||
|             } | ||||
|         } else if (assetProxyId == ERC1155_PROXY_ID) { | ||||
|             // Get ERC1155 token address | ||||
|             (, address tokenAddress, , , ) = decodeERC1155AssetData(assetData); | ||||
|  | ||||
|             // Encode data for `isApprovedForAll(ownerAddress, _ERC1155_PROXY_ADDRESS)` | ||||
|             bytes memory isApprovedForAllData = abi.encodeWithSelector( | ||||
|                 _ERC1155_IS_APPROVED_FOR_ALL_SELECTOR, | ||||
|                 ownerAddress, | ||||
|                 _ERC1155_PROXY_ADDRESS | ||||
|             ); | ||||
|  | ||||
|             // Query allowance | ||||
|             (bool success, bytes memory returnData) = tokenAddress.staticcall(isApprovedForAllData); | ||||
|             allowance = success && returnData.length == 32 && returnData.readUint256(0) == 1 ? _MAX_UINT256 : 0; | ||||
|         } else if (assetProxyId == STATIC_CALL_PROXY_ID) { | ||||
|             // The StaticCallProxy does not require any approvals | ||||
|             allowance = _MAX_UINT256; | ||||
|         } | ||||
|  | ||||
|         // Allowance will be 0 if the assetProxyId is unknown | ||||
|         return allowance; | ||||
|     } | ||||
|  | ||||
|     /// @dev Calls getAssetProxyAllowance() for each element of assetData. | ||||
|     /// @param ownerAddress Owner of the assets specified by assetData. | ||||
|     /// @param assetData Array of asset details, each encoded per the AssetProxy contract specification. | ||||
|     /// @return An array of asset allowances from getAllowance(), with each | ||||
|     /// element corresponding to the same-indexed element in the assetData input. | ||||
|     function getBatchAssetProxyAllowances(address ownerAddress, bytes[] memory assetData) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory allowances) | ||||
|     { | ||||
|         uint256 length = assetData.length; | ||||
|         allowances = new uint256[](length); | ||||
|         for (uint256 i = 0; i != length; i++) { | ||||
|             allowances[i] = getAssetProxyAllowance(ownerAddress, assetData[i]); | ||||
|         } | ||||
|         return allowances; | ||||
|     } | ||||
|  | ||||
|     /// @dev Calls getBalance() and getAllowance() for assetData. | ||||
|     /// @param ownerAddress Owner of the assets specified by assetData. | ||||
|     /// @param assetData Details of asset, encoded per the AssetProxy contract specification. | ||||
|     /// @return Number of assets (or asset baskets) held by owner, and number | ||||
|     /// of assets (or asset baskets) that the corresponding AssetProxy is authorized to spend. | ||||
|     function getBalanceAndAssetProxyAllowance(address ownerAddress, bytes memory assetData) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256 balance, uint256 allowance) | ||||
|     { | ||||
|         balance = getBalance(ownerAddress, assetData); | ||||
|         allowance = getAssetProxyAllowance(ownerAddress, assetData); | ||||
|         return (balance, allowance); | ||||
|     } | ||||
|  | ||||
|     /// @dev Calls getBatchBalances() and getBatchAllowances() for each element of assetData. | ||||
|     /// @param ownerAddress Owner of the assets specified by assetData. | ||||
|     /// @param assetData Array of asset details, each encoded per the AssetProxy contract specification. | ||||
|     /// @return An array of asset balances from getBalance(), and an array of | ||||
|     /// asset allowances from getAllowance(), with each element | ||||
|     /// corresponding to the same-indexed element in the assetData input. | ||||
|     function getBatchBalancesAndAssetProxyAllowances(address ownerAddress, bytes[] memory assetData) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory balances, uint256[] memory allowances) | ||||
|     { | ||||
|         balances = getBatchBalances(ownerAddress, assetData); | ||||
|         allowances = getBatchAssetProxyAllowances(ownerAddress, assetData); | ||||
|         return (balances, allowances); | ||||
|     } | ||||
|  | ||||
|     /// @dev Encode ERC-20 asset data into the format described in the AssetProxy contract specification. | ||||
|     /// @param tokenAddress The address of the ERC-20 contract hosting the asset to be traded. | ||||
|     /// @return AssetProxy-compliant data describing the asset. | ||||
|     function encodeERC20AssetData(address tokenAddress) | ||||
|         public | ||||
|         pure | ||||
|         returns (bytes memory assetData) | ||||
|     { | ||||
|         assetData = abi.encodeWithSelector(ERC20_PROXY_ID, tokenAddress); | ||||
|         return assetData; | ||||
|     } | ||||
|  | ||||
|     /// @dev Decode ERC-20 asset data from the format described in the AssetProxy contract specification. | ||||
|     /// @param assetData AssetProxy-compliant asset data describing an ERC-20 asset. | ||||
|     /// @return The ERC-20 AssetProxy identifier, and the address of the ERC-20  | ||||
|     /// contract hosting this asset. | ||||
|     function decodeERC20AssetData(bytes memory assetData) | ||||
|         public | ||||
|         pure | ||||
|         returns ( | ||||
|             bytes4 assetProxyId, | ||||
|             address tokenAddress | ||||
|         ) | ||||
|     { | ||||
|         assetProxyId = assetData.readBytes4(0); | ||||
|  | ||||
|         require( | ||||
|             assetProxyId == ERC20_PROXY_ID, | ||||
|             "WRONG_PROXY_ID" | ||||
|         ); | ||||
|  | ||||
|         tokenAddress = assetData.readAddress(16); | ||||
|         return (assetProxyId, tokenAddress); | ||||
|     } | ||||
|  | ||||
|     /// @dev Encode ERC-721 asset data into the format described in the AssetProxy specification. | ||||
|     /// @param tokenAddress The address of the ERC-721 contract hosting the asset to be traded. | ||||
|     /// @param tokenId The identifier of the specific asset to be traded. | ||||
|     /// @return AssetProxy-compliant asset data describing the asset. | ||||
|     function encodeERC721AssetData(address tokenAddress, uint256 tokenId) | ||||
|         public | ||||
|         pure | ||||
|         returns (bytes memory assetData) | ||||
|     { | ||||
|         assetData = abi.encodeWithSelector( | ||||
|             ERC721_PROXY_ID, | ||||
|             tokenAddress, | ||||
|             tokenId | ||||
|         ); | ||||
|         return assetData; | ||||
|     } | ||||
|  | ||||
|     /// @dev Decode ERC-721 asset data from the format described in the AssetProxy contract specification. | ||||
|     /// @param assetData AssetProxy-compliant asset data describing an ERC-721 asset. | ||||
|     /// @return The ERC-721 AssetProxy identifier, the address of the ERC-721 | ||||
|     /// contract hosting this asset, and the identifier of the specific | ||||
|     /// asset to be traded. | ||||
|     function decodeERC721AssetData(bytes memory assetData) | ||||
|         public | ||||
|         pure | ||||
|         returns ( | ||||
|             bytes4 assetProxyId, | ||||
|             address tokenAddress, | ||||
|             uint256 tokenId | ||||
|         ) | ||||
|     { | ||||
|         assetProxyId = assetData.readBytes4(0); | ||||
|  | ||||
|         require( | ||||
|             assetProxyId == ERC721_PROXY_ID, | ||||
|             "WRONG_PROXY_ID" | ||||
|         ); | ||||
|  | ||||
|         tokenAddress = assetData.readAddress(16); | ||||
|         tokenId = assetData.readUint256(36); | ||||
|         return (assetProxyId, tokenAddress, tokenId); | ||||
|     } | ||||
|  | ||||
|     /// @dev Encode ERC-1155 asset data into the format described in the AssetProxy contract specification. | ||||
|     /// @param tokenAddress The address of the ERC-1155 contract hosting the asset(s) to be traded. | ||||
|     /// @param tokenIds The identifiers of the specific assets to be traded. | ||||
|     /// @param tokenValues The amounts of each asset to be traded. | ||||
|     /// @param callbackData Data to be passed to receiving contracts when a transfer is performed. | ||||
|     /// @return AssetProxy-compliant asset data describing the set of assets. | ||||
|     function encodeERC1155AssetData( | ||||
|         address tokenAddress, | ||||
|         uint256[] memory tokenIds, | ||||
|         uint256[] memory tokenValues, | ||||
|         bytes memory callbackData | ||||
|     ) | ||||
|         public | ||||
|         pure | ||||
|         returns (bytes memory assetData) | ||||
|     { | ||||
|         assetData = abi.encodeWithSelector( | ||||
|             ERC1155_PROXY_ID, | ||||
|             tokenAddress, | ||||
|             tokenIds, | ||||
|             tokenValues, | ||||
|             callbackData | ||||
|         ); | ||||
|         return assetData; | ||||
|     } | ||||
|  | ||||
|     /// @dev Decode ERC-1155 asset data from the format described in the AssetProxy contract specification. | ||||
|     /// @param assetData AssetProxy-compliant asset data describing an ERC-1155 set of assets. | ||||
|     /// @return The ERC-1155 AssetProxy identifier, the address of the ERC-1155 | ||||
|     /// contract hosting the assets, an array of the identifiers of the | ||||
|     /// assets to be traded, an array of asset amounts to be traded, and | ||||
|     /// callback data.  Each element of the arrays corresponds to the | ||||
|     /// same-indexed element of the other array.  Return values specified as | ||||
|     /// `memory` are returned as pointers to locations within the memory of | ||||
|     /// the input parameter `assetData`. | ||||
|     function decodeERC1155AssetData(bytes memory assetData) | ||||
|         public | ||||
|         pure | ||||
|         returns ( | ||||
|             bytes4 assetProxyId, | ||||
|             address tokenAddress, | ||||
|             uint256[] memory tokenIds, | ||||
|             uint256[] memory tokenValues, | ||||
|             bytes memory callbackData | ||||
|         ) | ||||
|     { | ||||
|         assetProxyId = assetData.readBytes4(0); | ||||
|  | ||||
|         require( | ||||
|             assetProxyId == ERC1155_PROXY_ID, | ||||
|             "WRONG_PROXY_ID" | ||||
|         ); | ||||
|  | ||||
|         assembly { | ||||
|             // Skip selector and length to get to the first parameter: | ||||
|             assetData := add(assetData, 36) | ||||
|             // Read the value of the first parameter: | ||||
|             tokenAddress := mload(assetData) | ||||
|             // Point to the next parameter's data: | ||||
|             tokenIds := add(assetData, mload(add(assetData, 32))) | ||||
|             // Point to the next parameter's data: | ||||
|             tokenValues := add(assetData, mload(add(assetData, 64))) | ||||
|             // Point to the next parameter's data: | ||||
|             callbackData := add(assetData, mload(add(assetData, 96))) | ||||
|         } | ||||
|  | ||||
|         return ( | ||||
|             assetProxyId, | ||||
|             tokenAddress, | ||||
|             tokenIds, | ||||
|             tokenValues, | ||||
|             callbackData | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Encode data for multiple assets, per the AssetProxy contract specification. | ||||
|     /// @param amounts The amounts of each asset to be traded. | ||||
|     /// @param nestedAssetData AssetProxy-compliant data describing each asset to be traded. | ||||
|     /// @return AssetProxy-compliant data describing the set of assets. | ||||
|     function encodeMultiAssetData(uint256[] memory amounts, bytes[] memory nestedAssetData) | ||||
|         public | ||||
|         pure | ||||
|         returns (bytes memory assetData) | ||||
|     { | ||||
|         assetData = abi.encodeWithSelector( | ||||
|             MULTI_ASSET_PROXY_ID, | ||||
|             amounts, | ||||
|             nestedAssetData | ||||
|         ); | ||||
|         return assetData; | ||||
|     } | ||||
|  | ||||
|     /// @dev Decode multi-asset data from the format described in the AssetProxy contract specification. | ||||
|     /// @param assetData AssetProxy-compliant data describing a multi-asset basket. | ||||
|     /// @return The Multi-Asset AssetProxy identifier, an array of the amounts | ||||
|     /// of the assets to be traded, and an array of the | ||||
|     /// AssetProxy-compliant data describing each asset to be traded.  Each | ||||
|     /// element of the arrays corresponds to the same-indexed element of the other array. | ||||
|     function decodeMultiAssetData(bytes memory assetData) | ||||
|         public | ||||
|         pure | ||||
|         returns ( | ||||
|             bytes4 assetProxyId, | ||||
|             uint256[] memory amounts, | ||||
|             bytes[] memory nestedAssetData | ||||
|         ) | ||||
|     { | ||||
|         assetProxyId = assetData.readBytes4(0); | ||||
|  | ||||
|         require( | ||||
|             assetProxyId == MULTI_ASSET_PROXY_ID, | ||||
|             "WRONG_PROXY_ID" | ||||
|         ); | ||||
|  | ||||
|         // solhint-disable indent | ||||
|         (amounts, nestedAssetData) = abi.decode( | ||||
|             assetData.slice(4, assetData.length), | ||||
|             (uint256[], bytes[]) | ||||
|         ); | ||||
|         // solhint-enable indent | ||||
|     } | ||||
|  | ||||
|     /// @dev Calls `asset.ownerOf(tokenId)`, but returns a null owner instead of reverting on an unowned asset. | ||||
|     /// @param tokenAddress Address of ERC721 asset. | ||||
|     /// @param tokenId The identifier for the specific NFT. | ||||
|     /// @return Owner of tokenId or null address if unowned. | ||||
|     function getERC721TokenOwner(address tokenAddress, uint256 tokenId) | ||||
|         public | ||||
|         view | ||||
|         returns (address ownerAddress) | ||||
|     { | ||||
|         bytes memory ownerOfCalldata = abi.encodeWithSelector( | ||||
|             _ERC721_OWNER_OF_SELECTOR, | ||||
|             tokenId | ||||
|         ); | ||||
|  | ||||
|         (bool success, bytes memory returnData) = tokenAddress.staticcall(ownerOfCalldata); | ||||
|  | ||||
|         ownerAddress = (success && returnData.length == 32) ? returnData.readAddress(12) : address(0); | ||||
|         return ownerAddress; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										193
									
								
								contracts/dev-utils/contracts/src/LibTransactionDecoder.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								contracts/dev-utils/contracts/src/LibTransactionDecoder.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2019 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.5.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-exchange-libs/contracts/src/LibExchangeSelectors.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibBytes.sol"; | ||||
|  | ||||
|  | ||||
| contract LibTransactionDecoder is | ||||
|     LibExchangeSelectors | ||||
| { | ||||
|     using LibBytes for bytes; | ||||
|  | ||||
|     /// @dev Decodes the call data for an Exchange contract method call. | ||||
|     /// @param transactionData ABI-encoded calldata for an Exchange | ||||
|     ///     contract method call. | ||||
|     /// @return The name of the function called, and the parameters it was | ||||
|     ///     given.  For single-order fills and cancels, the arrays will have | ||||
|     ///     just one element. | ||||
|     function decodeZeroExTransactionData(bytes memory transactionData) | ||||
|         public | ||||
|         pure | ||||
|         returns( | ||||
|             string memory functionName, | ||||
|             LibOrder.Order[] memory orders, | ||||
|             uint256[] memory takerAssetFillAmounts, | ||||
|             bytes[] memory signatures | ||||
|         ) | ||||
|     { | ||||
|         bytes4 functionSelector = transactionData.readBytes4(0); | ||||
|  | ||||
|         if (functionSelector == BATCH_CANCEL_ORDERS_SELECTOR) { | ||||
|             functionName = "batchCancelOrders"; | ||||
|         } else if (functionSelector == BATCH_FILL_ORDERS_SELECTOR) { | ||||
|             functionName = "batchFillOrders"; | ||||
|         } else if (functionSelector == BATCH_FILL_ORDERS_NO_THROW_SELECTOR) { | ||||
|             functionName = "batchFillOrdersNoThrow"; | ||||
|         } else if (functionSelector == BATCH_FILL_OR_KILL_ORDERS_SELECTOR) { | ||||
|             functionName = "batchFillOrKillOrders"; | ||||
|         } else if (functionSelector == CANCEL_ORDER_SELECTOR) { | ||||
|             functionName = "cancelOrder"; | ||||
|         } else if (functionSelector == FILL_ORDER_SELECTOR) { | ||||
|             functionName = "fillOrder"; | ||||
|         } else if (functionSelector == FILL_ORDER_NO_THROW_SELECTOR) { | ||||
|             functionName = "fillOrderNoThrow"; | ||||
|         } else if (functionSelector == FILL_OR_KILL_ORDER_SELECTOR) { | ||||
|             functionName = "fillOrKillOrder"; | ||||
|         } else if (functionSelector == MARKET_BUY_ORDERS_SELECTOR) { | ||||
|             functionName = "marketBuyOrders"; | ||||
|         } else if (functionSelector == MARKET_BUY_ORDERS_NO_THROW_SELECTOR) { | ||||
|             functionName = "marketBuyOrdersNoThrow"; | ||||
|         } else if (functionSelector == MARKET_SELL_ORDERS_SELECTOR) { | ||||
|             functionName = "marketSellOrders"; | ||||
|         } else if (functionSelector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR) { | ||||
|             functionName = "marketSellOrdersNoThrow"; | ||||
|         } else if (functionSelector == MATCH_ORDERS_SELECTOR) { | ||||
|             functionName = "matchOrders"; | ||||
|         } else if ( | ||||
|             functionSelector == CANCEL_ORDERS_UP_TO_SELECTOR || | ||||
|             functionSelector == EXECUTE_TRANSACTION_SELECTOR | ||||
|             // TODO: add new noThrow cancel functions when https://github.com/0xProject/ZEIPs/issues/35 is merged. | ||||
|         ) { | ||||
|             revert("UNIMPLEMENTED"); | ||||
|         } else { | ||||
|             revert("UNKNOWN_FUNCTION_SELECTOR"); | ||||
|         } | ||||
|  | ||||
|         if (functionSelector == BATCH_CANCEL_ORDERS_SELECTOR) { | ||||
|             // solhint-disable-next-line indent | ||||
|             orders = abi.decode(transactionData.slice(4, transactionData.length), (LibOrder.Order[])); | ||||
|             takerAssetFillAmounts = new uint256[](0); | ||||
|             signatures = new bytes[](0); | ||||
|         } else if ( | ||||
|             functionSelector == BATCH_FILL_OR_KILL_ORDERS_SELECTOR || | ||||
|             functionSelector == BATCH_FILL_ORDERS_NO_THROW_SELECTOR || | ||||
|             functionSelector == BATCH_FILL_ORDERS_SELECTOR | ||||
|         ) { | ||||
|             (orders, takerAssetFillAmounts, signatures) = _makeReturnValuesForBatchFill(transactionData); | ||||
|         } else if (functionSelector == CANCEL_ORDER_SELECTOR) { | ||||
|             orders = new LibOrder.Order[](1); | ||||
|             orders[0] = abi.decode(transactionData.slice(4, transactionData.length), (LibOrder.Order)); | ||||
|             takerAssetFillAmounts = new uint256[](0); | ||||
|             signatures = new bytes[](0); | ||||
|         } else if ( | ||||
|             functionSelector == FILL_OR_KILL_ORDER_SELECTOR || | ||||
|             functionSelector == FILL_ORDER_SELECTOR || | ||||
|             functionSelector == FILL_ORDER_NO_THROW_SELECTOR | ||||
|         ) { | ||||
|             (orders, takerAssetFillAmounts, signatures) = _makeReturnValuesForSingleOrderFill(transactionData); | ||||
|         } else if ( | ||||
|             functionSelector == MARKET_BUY_ORDERS_SELECTOR || | ||||
|             functionSelector == MARKET_BUY_ORDERS_NO_THROW_SELECTOR || | ||||
|             functionSelector == MARKET_SELL_ORDERS_SELECTOR || | ||||
|             functionSelector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR | ||||
|         ) { | ||||
|             (orders, takerAssetFillAmounts, signatures) = _makeReturnValuesForMarketFill(transactionData); | ||||
|         } else if (functionSelector == MATCH_ORDERS_SELECTOR) { | ||||
|             ( | ||||
|                 LibOrder.Order memory leftOrder, | ||||
|                 LibOrder.Order memory rightOrder, | ||||
|                 bytes memory leftSignature, | ||||
|                 bytes memory rightSignature | ||||
|             ) = abi.decode( | ||||
|                 transactionData.slice(4, transactionData.length), | ||||
|                 (LibOrder.Order, LibOrder.Order, bytes, bytes) | ||||
|             ); | ||||
|  | ||||
|             orders = new LibOrder.Order[](2); | ||||
|             orders[0] = leftOrder; | ||||
|             orders[1] = rightOrder; | ||||
|  | ||||
|             takerAssetFillAmounts = new uint256[](2); | ||||
|             takerAssetFillAmounts[0] = leftOrder.takerAssetAmount; | ||||
|             takerAssetFillAmounts[1] = rightOrder.takerAssetAmount; | ||||
|  | ||||
|             signatures = new bytes[](2); | ||||
|             signatures[0] = leftSignature; | ||||
|             signatures[1] = rightSignature; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function _makeReturnValuesForSingleOrderFill(bytes memory transactionData) | ||||
|         private | ||||
|         pure | ||||
|         returns( | ||||
|             LibOrder.Order[] memory orders, | ||||
|             uint256[] memory takerAssetFillAmounts, | ||||
|             bytes[] memory signatures | ||||
|         ) | ||||
|     { | ||||
|         orders = new LibOrder.Order[](1); | ||||
|         takerAssetFillAmounts = new uint256[](1); | ||||
|         signatures = new bytes[](1); | ||||
|         // solhint-disable-next-line indent | ||||
|         (orders[0], takerAssetFillAmounts[0], signatures[0]) = abi.decode( | ||||
|             transactionData.slice(4, transactionData.length), | ||||
|             (LibOrder.Order, uint256, bytes) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function _makeReturnValuesForBatchFill(bytes memory transactionData) | ||||
|         private | ||||
|         pure | ||||
|         returns( | ||||
|             LibOrder.Order[] memory orders, | ||||
|             uint256[] memory takerAssetFillAmounts, | ||||
|             bytes[] memory signatures | ||||
|         ) | ||||
|     { | ||||
|         // solhint-disable-next-line indent | ||||
|         (orders, takerAssetFillAmounts, signatures) = abi.decode( | ||||
|             transactionData.slice(4, transactionData.length), | ||||
|             // solhint-disable-next-line indent | ||||
|             (LibOrder.Order[], uint256[], bytes[]) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function _makeReturnValuesForMarketFill(bytes memory transactionData) | ||||
|         private | ||||
|         pure | ||||
|         returns( | ||||
|             LibOrder.Order[] memory orders, | ||||
|             uint256[] memory takerAssetFillAmounts, | ||||
|             bytes[] memory signatures | ||||
|         ) | ||||
|     { | ||||
|         takerAssetFillAmounts = new uint256[](1); | ||||
|         // solhint-disable-next-line indent | ||||
|         (orders, takerAssetFillAmounts[0], signatures) = abi.decode( | ||||
|             transactionData.slice(4, transactionData.length), | ||||
|             // solhint-disable-next-line indent | ||||
|             (LibOrder.Order[], uint256, bytes[]) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										184
									
								
								contracts/dev-utils/contracts/src/OrderValidationUtils.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								contracts/dev-utils/contracts/src/OrderValidationUtils.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| /* | ||||
|  | ||||
|   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.5.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibBytes.sol"; | ||||
| import "./LibAssetData.sol"; | ||||
|  | ||||
|  | ||||
| contract OrderValidationUtils is | ||||
|     LibAssetData, | ||||
|     LibMath | ||||
| { | ||||
|     using LibBytes for bytes; | ||||
|  | ||||
|     // solhint-disable var-name-mixedcase | ||||
|     bytes internal _ZRX_ASSET_DATA; | ||||
|     // solhint-enable var-name-mixedcase | ||||
|  | ||||
|     constructor (address _exchange, bytes memory _zrxAssetData) | ||||
|         public | ||||
|         LibAssetData(_exchange) | ||||
|     { | ||||
|         _ZRX_ASSET_DATA = _zrxAssetData; | ||||
|     } | ||||
|  | ||||
|     /// @dev Fetches all order-relevant information needed to validate if the supplied order is fillable. | ||||
|     /// @param order The order structure. | ||||
|     /// @param signature Signature provided by maker that proves the order's authenticity. | ||||
|     /// `0x01` can always be provided if the signature does not need to be validated. | ||||
|     /// @return The orderInfo (hash, status, and `takerAssetAmount` already filled for the given order), | ||||
|     /// fillableTakerAssetAmount (amount of the order's `takerAssetAmount` that is fillable given all on-chain state), | ||||
|     /// and isValidSignature (validity of the provided signature). | ||||
|     /// NOTE: If the `takerAssetData` encodes data for multiple assets, `fillableTakerAssetAmount` will represent a "scaled" | ||||
|     /// amount, meaning it must be multiplied by all the individual asset amounts within the `takerAssetData` to get the final | ||||
|     /// amount of each asset that can be filled. | ||||
|     function getOrderRelevantState(LibOrder.Order memory order, bytes memory signature) | ||||
|         public | ||||
|         view | ||||
|         returns ( | ||||
|             LibOrder.OrderInfo memory orderInfo, | ||||
|             uint256 fillableTakerAssetAmount, | ||||
|             bool isValidSignature | ||||
|         ) | ||||
|     { | ||||
|         // Get info specific to order | ||||
|         orderInfo = _EXCHANGE.getOrderInfo(order); | ||||
|  | ||||
|         // Validate the maker's signature | ||||
|         address makerAddress = order.makerAddress; | ||||
|         isValidSignature = _EXCHANGE.isValidSignature( | ||||
|             orderInfo.orderHash, | ||||
|             makerAddress, | ||||
|             signature | ||||
|         ); | ||||
|  | ||||
|         // Get the transferable amount of the `makerAsset` | ||||
|         uint256 transferableMakerAssetAmount = getTransferableAssetAmount(makerAddress, order.makerAssetData); | ||||
|  | ||||
|         // Assign to stack variables to reduce redundant mloads/sloads | ||||
|         uint256 takerAssetAmount = order.takerAssetAmount; | ||||
|         uint256 makerFee = order.makerFee; | ||||
|         bytes memory zrxAssetData = _ZRX_ASSET_DATA; | ||||
|      | ||||
|         // Get the amount of `takerAsset` that is transferable to maker given the transferability of `makerAsset`, `makerFeeAsset`, | ||||
|         // and the total amounts specified in the order | ||||
|         uint256 transferableTakerAssetAmount; | ||||
|         if (order.makerAssetData.equals(zrxAssetData)) { | ||||
|             // If `makerAsset` equals `makerFeeAsset`, the % that can be filled is | ||||
|             // transferableMakerAssetAmount / (makerAssetAmount + makerFee) | ||||
|             transferableTakerAssetAmount = getPartialAmountFloor( | ||||
|                 transferableMakerAssetAmount, | ||||
|                 safeAdd(order.makerAssetAmount, makerFee), | ||||
|                 takerAssetAmount | ||||
|             ); | ||||
|         } else { | ||||
|             // Get the transferable amount of the `makerFeeAsset` | ||||
|             uint256 transferableMakerFeeAssetAmount = getTransferableAssetAmount(makerAddress, zrxAssetData); | ||||
|  | ||||
|             // If `makerFee` is 0, the % that can be filled is (transferableMakerAssetAmount / makerAssetAmount) | ||||
|             if (makerFee == 0) { | ||||
|                 transferableTakerAssetAmount = getPartialAmountFloor( | ||||
|                     transferableMakerAssetAmount, | ||||
|                     order.makerAssetAmount, | ||||
|                     takerAssetAmount | ||||
|                 ); | ||||
|  | ||||
|             // If `makerAsset` does not equal `makerFeeAsset`, the % that can be filled is the lower of | ||||
|             // (transferableMakerAssetAmount / makerAssetAmount) and (transferableMakerAssetFeeAmount / makerFee) | ||||
|             } else { | ||||
|                 uint256 transferableMakerToTakerAmount = getPartialAmountFloor( | ||||
|                     transferableMakerAssetAmount, | ||||
|                     order.makerAssetAmount, | ||||
|                     takerAssetAmount | ||||
|                 ); | ||||
|                 uint256 transferableMakerFeeToTakerAmount = getPartialAmountFloor( | ||||
|                     transferableMakerFeeAssetAmount, | ||||
|                     makerFee, | ||||
|                     takerAssetAmount | ||||
|                 ); | ||||
|                 transferableTakerAssetAmount = min256(transferableMakerToTakerAmount, transferableMakerFeeToTakerAmount); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // `fillableTakerAssetAmount` is the lower of the order's remaining `takerAssetAmount` and the `transferableTakerAssetAmount` | ||||
|         fillableTakerAssetAmount = min256( | ||||
|             safeSub(takerAssetAmount, orderInfo.orderTakerAssetFilledAmount), | ||||
|             transferableTakerAssetAmount | ||||
|         ); | ||||
|  | ||||
|         return (orderInfo, fillableTakerAssetAmount, isValidSignature); | ||||
|     } | ||||
|  | ||||
|     /// @dev Fetches all order-relevant information needed to validate if the supplied orders are fillable. | ||||
|     /// @param orders Array of order structures. | ||||
|     /// @param signatures Array of signatures provided by makers that prove the authenticity of the orders. | ||||
|     /// `0x01` can always be provided if a signature does not need to be validated. | ||||
|     /// @return The ordersInfo (array of the hash, status, and `takerAssetAmount` already filled for each order), | ||||
|     /// fillableTakerAssetAmounts (array of amounts for each order's `takerAssetAmount` that is fillable given all on-chain state), | ||||
|     /// and isValidSignature (array containing the validity of each provided signature). | ||||
|     /// NOTE: If the `takerAssetData` encodes data for multiple assets, each element of `fillableTakerAssetAmounts` | ||||
|     /// will represent a "scaled" amount, meaning it must be multiplied by all the individual asset amounts within | ||||
|     /// the `takerAssetData` to get the final amount of each asset that can be filled. | ||||
|     function getOrderRelevantStates(LibOrder.Order[] memory orders, bytes[] memory signatures) | ||||
|         public | ||||
|         view | ||||
|         returns ( | ||||
|             LibOrder.OrderInfo[] memory ordersInfo, | ||||
|             uint256[] memory fillableTakerAssetAmounts, | ||||
|             bool[] memory isValidSignature | ||||
|         ) | ||||
|     { | ||||
|         uint256 length = orders.length; | ||||
|         ordersInfo = new LibOrder.OrderInfo[](length); | ||||
|         fillableTakerAssetAmounts = new uint256[](length); | ||||
|         isValidSignature = new bool[](length); | ||||
|  | ||||
|         for (uint256 i = 0; i != length; i++) { | ||||
|             (ordersInfo[i], fillableTakerAssetAmounts[i], isValidSignature[i]) = getOrderRelevantState( | ||||
|                 orders[i], | ||||
|                 signatures[i] | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return (ordersInfo, fillableTakerAssetAmounts, isValidSignature); | ||||
|     } | ||||
|  | ||||
|     /// @dev Gets the amount of an asset transferable by the owner. | ||||
|     /// @param ownerAddress Address of the owner of the asset. | ||||
|     /// @param assetData Description of tokens, per the AssetProxy contract specification. | ||||
|     /// @return The amount of the asset tranferable by the owner. | ||||
|     /// NOTE: If the `assetData` encodes data for multiple assets, the `transferableAssetAmount` | ||||
|     /// will represent the amount of times the entire `assetData` can be transferred. To calculate | ||||
|     /// the total individual transferable amounts, this scaled `transferableAmount` must be multiplied by  | ||||
|     /// the individual asset amounts located within the `assetData`. | ||||
|     function getTransferableAssetAmount(address ownerAddress, bytes memory assetData) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256 transferableAssetAmount) | ||||
|     { | ||||
|         (uint256 balance, uint256 allowance) = getBalanceAndAssetProxyAllowance(ownerAddress, assetData); | ||||
|         transferableAssetAmount = min256(balance, allowance); | ||||
|         return transferableAssetAmount; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										91
									
								
								contracts/dev-utils/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								contracts/dev-utils/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-dev-utils", | ||||
|     "version": "0.0.7", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
|     "description": "0x protocol specific utility contracts", | ||||
|     "main": "lib/src/index.js", | ||||
|     "directories": { | ||||
|         "test": "test" | ||||
|     }, | ||||
|     "scripts": { | ||||
|         "build": "yarn pre_build && tsc -b", | ||||
|         "build:ci": "yarn build", | ||||
|         "pre_build": "run-s compile generate_contract_wrappers", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild_and_test": "run-s build test", | ||||
|         "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", | ||||
|         "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", | ||||
|         "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", | ||||
|         "fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", | ||||
|         "coverage:report:text": "istanbul report text", | ||||
|         "coverage:report:html": "istanbul report html && open coverage/index.html", | ||||
|         "profiler:report:html": "istanbul report html && open coverage/index.html", | ||||
|         "coverage:report:lcov": "istanbul report lcov", | ||||
|         "test:circleci": "yarn test", | ||||
|         "contracts:gen": "contracts-gen", | ||||
|         "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol" | ||||
|     }, | ||||
|     "config": { | ||||
|         "abis": "./generated-artifacts/@(DevUtils|LibAssetData|LibTransactionDecoder|EthBalanceChecker).json", | ||||
|         "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually." | ||||
|     }, | ||||
|     "repository": { | ||||
|         "type": "git", | ||||
|         "url": "https://github.com/0xProject/0x-monorepo.git" | ||||
|     }, | ||||
|     "license": "Apache-2.0", | ||||
|     "bugs": { | ||||
|         "url": "https://github.com/0xProject/0x-monorepo/issues" | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/dev-utils/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^4.1.0", | ||||
|         "@0x/contracts-gen": "^1.0.13", | ||||
|         "@0x/contracts-test-utils": "^3.1.13", | ||||
|         "@0x/dev-utils": "^2.3.0", | ||||
|         "@0x/sol-compiler": "^3.1.12", | ||||
|         "@0x/tslint-config": "^3.0.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
|         "solhint": "^1.4.1", | ||||
|         "tslint": "5.11.0", | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^5.3.1", | ||||
|         "@0x/contracts-asset-proxy": "^2.2.5", | ||||
|         "@0x/contracts-erc1155": "^1.1.12", | ||||
|         "@0x/contracts-erc20": "^2.2.11", | ||||
|         "@0x/contracts-erc721": "^2.1.12", | ||||
|         "@0x/contracts-exchange": "^2.1.11", | ||||
|         "@0x/contracts-exchange-libs": "^3.0.5", | ||||
|         "@0x/contracts-utils": "^3.2.1", | ||||
|         "@0x/order-utils": "^8.2.5", | ||||
|         "@0x/types": "^2.4.1", | ||||
|         "@0x/typescript-typings": "^4.2.4", | ||||
|         "@0x/utils": "^4.5.0", | ||||
|         "@0x/web3-wrapper": "^6.0.10", | ||||
|         "ethereum-types": "^2.1.4", | ||||
|         "ethereumjs-util": "^5.1.1" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|     } | ||||
| } | ||||
							
								
								
									
										15
									
								
								contracts/dev-utils/src/artifacts.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								contracts/dev-utils/src/artifacts.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| /* | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
| import { ContractArtifact } from 'ethereum-types'; | ||||
|  | ||||
| import * as DevUtils from '../generated-artifacts/DevUtils.json'; | ||||
| import * as LibAssetData from '../generated-artifacts/LibAssetData.json'; | ||||
| import * as LibTransactionDecoder from '../generated-artifacts/LibTransactionDecoder.json'; | ||||
| export const artifacts = { | ||||
|     DevUtils: DevUtils as ContractArtifact, | ||||
|     LibTransactionDecoder: LibTransactionDecoder as ContractArtifact, | ||||
|     LibAssetData: LibAssetData as ContractArtifact, | ||||
| }; | ||||
							
								
								
									
										2
									
								
								contracts/dev-utils/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								contracts/dev-utils/src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| export * from './artifacts'; | ||||
| export * from './wrappers'; | ||||
							
								
								
									
										8
									
								
								contracts/dev-utils/src/wrappers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								contracts/dev-utils/src/wrappers.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| /* | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
| export * from '../generated-wrappers/dev_utils'; | ||||
| export * from '../generated-wrappers/lib_asset_data'; | ||||
| export * from '../generated-wrappers/lib_transaction_decoder'; | ||||
| @@ -2,6 +2,7 @@ import { env, EnvVars } from '@0x/dev-utils'; | ||||
| 
 | ||||
| import { coverage, profiler, provider } from '@0x/contracts-test-utils'; | ||||
| import { providerUtils } from '@0x/utils'; | ||||
| 
 | ||||
| before('start web3 provider', () => { | ||||
|     providerUtils.startProviderEngine(provider); | ||||
| }); | ||||
							
								
								
									
										538
									
								
								contracts/dev-utils/test/lib_asset_data.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										538
									
								
								contracts/dev-utils/test/lib_asset_data.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,538 @@ | ||||
| import * as chai from 'chai'; | ||||
| import { LogWithDecodedArgs } from 'ethereum-types'; | ||||
|  | ||||
| import { | ||||
|     artifacts as proxyArtifacts, | ||||
|     ERC1155ProxyContract, | ||||
|     ERC20ProxyContract, | ||||
|     ERC721ProxyContract, | ||||
|     MultiAssetProxyContract, | ||||
|     StaticCallProxyContract, | ||||
|     TestStaticCallTargetContract, | ||||
| } from '@0x/contracts-asset-proxy'; | ||||
| import { | ||||
|     artifacts as erc1155Artifacts, | ||||
|     ERC1155MintableContract, | ||||
|     ERC1155TransferSingleEventArgs, | ||||
| } from '@0x/contracts-erc1155'; | ||||
| import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20'; | ||||
| import { artifacts as erc721Artifacts, DummyERC721TokenContract } from '@0x/contracts-erc721'; | ||||
| import { artifacts as exchangeArtifacts, ExchangeContract } from '@0x/contracts-exchange'; | ||||
| import { chaiSetup, constants, LogDecoder, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils'; | ||||
| import { BlockchainLifecycle } from '@0x/dev-utils'; | ||||
| import { assetDataUtils } from '@0x/order-utils'; | ||||
| import { AssetProxyId } from '@0x/types'; | ||||
| import { BigNumber } from '@0x/utils'; | ||||
| import * as ethUtil from 'ethereumjs-util'; | ||||
|  | ||||
| import { artifacts, LibAssetDataContract } from '../src'; | ||||
|  | ||||
| chaiSetup.configure(); | ||||
| const expect = chai.expect; | ||||
|  | ||||
| const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); | ||||
|  | ||||
| const KNOWN_ERC20_ENCODING = { | ||||
|     address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48', | ||||
|     assetData: '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48', | ||||
| }; | ||||
| const KNOWN_ERC721_ENCODING = { | ||||
|     address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48', | ||||
|     tokenId: new BigNumber(1), | ||||
|     assetData: | ||||
|         '0x025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001', | ||||
| }; | ||||
| const KNOWN_ERC1155_ENCODING = { | ||||
|     tokenAddress: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48', | ||||
|     tokenIds: [new BigNumber(100), new BigNumber(1001), new BigNumber(10001)], | ||||
|     tokenValues: [new BigNumber(200), new BigNumber(2001), new BigNumber(20001)], | ||||
|     callbackData: | ||||
|         '0x025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001', | ||||
|     assetData: | ||||
|         '0xa7cb5fb70000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000', | ||||
| }; | ||||
| const KNOWN_MULTI_ASSET_ENCODING = { | ||||
|     amounts: [new BigNumber(70), new BigNumber(1), new BigNumber(18)], | ||||
|     nestedAssetData: [ | ||||
|         KNOWN_ERC20_ENCODING.assetData, | ||||
|         KNOWN_ERC721_ENCODING.assetData, | ||||
|         KNOWN_ERC1155_ENCODING.assetData, | ||||
|     ], | ||||
|     assetData: | ||||
|         '0x94cfcdd7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204a7cb5fb70000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c4800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', | ||||
| }; | ||||
|  | ||||
| describe('LibAssetData', () => { | ||||
|     let exchange: ExchangeContract; | ||||
|     let erc20Proxy: ERC20ProxyContract; | ||||
|     let erc721Proxy: ERC721ProxyContract; | ||||
|     let erc1155Proxy: ERC1155ProxyContract; | ||||
|     let multiAssetProxy: MultiAssetProxyContract; | ||||
|     let staticCallProxy: StaticCallProxyContract; | ||||
|     let staticCallTarget: TestStaticCallTargetContract; | ||||
|     let libAssetData: LibAssetDataContract; | ||||
|  | ||||
|     let tokenOwnerAddress: string; | ||||
|  | ||||
|     let erc20Token: DummyERC20TokenContract; | ||||
|     let erc721Token: DummyERC721TokenContract; | ||||
|     let erc1155Token: ERC1155MintableContract; | ||||
|  | ||||
|     const erc20TokenTotalSupply = new BigNumber(1); | ||||
|  | ||||
|     const firstERC721TokenId = new BigNumber(1); | ||||
|     const numberOfERC721Tokens = 10; | ||||
|  | ||||
|     let erc1155TokenId: BigNumber; | ||||
|  | ||||
|     before(async () => { | ||||
|         await blockchainLifecycle.startAsync(); | ||||
|  | ||||
|         exchange = await ExchangeContract.deployFrom0xArtifactAsync( | ||||
|             exchangeArtifacts.Exchange, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             constants.NULL_BYTES, | ||||
|         ); | ||||
|  | ||||
|         erc20Proxy = await ERC20ProxyContract.deployFrom0xArtifactAsync( | ||||
|             proxyArtifacts.ERC20Proxy, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         erc721Proxy = await ERC721ProxyContract.deployFrom0xArtifactAsync( | ||||
|             proxyArtifacts.ERC721Proxy, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         erc1155Proxy = await ERC1155ProxyContract.deployFrom0xArtifactAsync( | ||||
|             proxyArtifacts.ERC1155Proxy, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         multiAssetProxy = await MultiAssetProxyContract.deployFrom0xArtifactAsync( | ||||
|             proxyArtifacts.MultiAssetProxy, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         staticCallProxy = await StaticCallProxyContract.deployFrom0xArtifactAsync( | ||||
|             proxyArtifacts.StaticCallProxy, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|  | ||||
|         await exchange.registerAssetProxy.awaitTransactionSuccessAsync(erc20Proxy.address); | ||||
|         await exchange.registerAssetProxy.awaitTransactionSuccessAsync(erc721Proxy.address); | ||||
|         await exchange.registerAssetProxy.awaitTransactionSuccessAsync(erc1155Proxy.address); | ||||
|         await exchange.registerAssetProxy.awaitTransactionSuccessAsync(multiAssetProxy.address); | ||||
|         await exchange.registerAssetProxy.awaitTransactionSuccessAsync(staticCallProxy.address); | ||||
|  | ||||
|         libAssetData = await LibAssetDataContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.LibAssetData, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             exchange.address, | ||||
|         ); | ||||
|  | ||||
|         staticCallTarget = await TestStaticCallTargetContract.deployFrom0xArtifactAsync( | ||||
|             proxyArtifacts.TestStaticCallTarget, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|  | ||||
|         [tokenOwnerAddress] = await web3Wrapper.getAvailableAddressesAsync(); | ||||
|  | ||||
|         erc20Token = await DummyERC20TokenContract.deployFrom0xArtifactAsync( | ||||
|             erc20Artifacts.DummyERC20Token, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             'Dummy', | ||||
|             'DUM', | ||||
|             new BigNumber(1), | ||||
|             erc20TokenTotalSupply, | ||||
|         ); | ||||
|  | ||||
|         erc721Token = await DummyERC721TokenContract.deployFrom0xArtifactAsync( | ||||
|             erc721Artifacts.DummyERC721Token, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             'Dummy', | ||||
|             'DUM', | ||||
|         ); | ||||
|         // mint `numberOfERC721Tokens` tokens | ||||
|         const transactionMinedPromises = []; | ||||
|         for (let i = 0; i < numberOfERC721Tokens; i++) { | ||||
|             transactionMinedPromises.push( | ||||
|                 erc721Token.mint.awaitTransactionSuccessAsync(tokenOwnerAddress, firstERC721TokenId.plus(i - 1)), | ||||
|             ); | ||||
|         } | ||||
|         await Promise.all(transactionMinedPromises); | ||||
|  | ||||
|         erc1155Token = await ERC1155MintableContract.deployFrom0xArtifactAsync( | ||||
|             erc1155Artifacts.ERC1155Mintable, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|  | ||||
|         const logDecoder = new LogDecoder(web3Wrapper, erc1155Artifacts); | ||||
|         const transactionReceipt = await logDecoder.getTxWithDecodedLogsAsync( | ||||
|             await erc1155Token.create.sendTransactionAsync('uri:Dummy', /*isNonFungible:*/ false), | ||||
|         ); | ||||
|  | ||||
|         // tslint:disable-next-line no-unnecessary-type-assertion | ||||
|         erc1155TokenId = (transactionReceipt.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>).args.id; | ||||
|         await erc1155Token.mintFungible.awaitTransactionSuccessAsync( | ||||
|             erc1155TokenId, | ||||
|             [tokenOwnerAddress], | ||||
|             [new BigNumber(1)], | ||||
|         ); | ||||
|     }); | ||||
|  | ||||
|     after(async () => { | ||||
|         await blockchainLifecycle.revertAsync(); | ||||
|     }); | ||||
|  | ||||
|     beforeEach(async () => { | ||||
|         await blockchainLifecycle.startAsync(); | ||||
|     }); | ||||
|     afterEach(async () => { | ||||
|         await blockchainLifecycle.revertAsync(); | ||||
|     }); | ||||
|  | ||||
|     it('should have a deployed-to address', () => { | ||||
|         expect(libAssetData.address.slice(0, 2)).to.equal('0x'); | ||||
|     }); | ||||
|  | ||||
|     describe('encoding and decoding', () => { | ||||
|         it('should encode ERC20 asset data', async () => { | ||||
|             expect(await libAssetData.encodeERC20AssetData.callAsync(KNOWN_ERC20_ENCODING.address)).to.equal( | ||||
|                 KNOWN_ERC20_ENCODING.assetData, | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it('should decode ERC20 asset data', async () => { | ||||
|             expect(await libAssetData.decodeERC20AssetData.callAsync(KNOWN_ERC20_ENCODING.assetData)).to.deep.equal([ | ||||
|                 AssetProxyId.ERC20, | ||||
|                 KNOWN_ERC20_ENCODING.address, | ||||
|             ]); | ||||
|         }); | ||||
|  | ||||
|         it('should encode ERC721 asset data', async () => { | ||||
|             expect( | ||||
|                 await libAssetData.encodeERC721AssetData.callAsync( | ||||
|                     KNOWN_ERC721_ENCODING.address, | ||||
|                     KNOWN_ERC721_ENCODING.tokenId, | ||||
|                 ), | ||||
|             ).to.equal(KNOWN_ERC721_ENCODING.assetData); | ||||
|         }); | ||||
|  | ||||
|         it('should decode ERC721 asset data', async () => { | ||||
|             expect(await libAssetData.decodeERC721AssetData.callAsync(KNOWN_ERC721_ENCODING.assetData)).to.deep.equal([ | ||||
|                 AssetProxyId.ERC721, | ||||
|                 KNOWN_ERC721_ENCODING.address, | ||||
|                 KNOWN_ERC721_ENCODING.tokenId, | ||||
|             ]); | ||||
|         }); | ||||
|  | ||||
|         it('should encode ERC1155 asset data', async () => { | ||||
|             expect( | ||||
|                 await libAssetData.encodeERC1155AssetData.callAsync( | ||||
|                     KNOWN_ERC1155_ENCODING.tokenAddress, | ||||
|                     KNOWN_ERC1155_ENCODING.tokenIds, | ||||
|                     KNOWN_ERC1155_ENCODING.tokenValues, | ||||
|                     KNOWN_ERC1155_ENCODING.callbackData, | ||||
|                 ), | ||||
|             ).to.equal(KNOWN_ERC1155_ENCODING.assetData); | ||||
|         }); | ||||
|  | ||||
|         it('should decode ERC1155 asset data', async () => { | ||||
|             expect(await libAssetData.decodeERC1155AssetData.callAsync(KNOWN_ERC1155_ENCODING.assetData)).to.deep.equal( | ||||
|                 [ | ||||
|                     AssetProxyId.ERC1155, | ||||
|                     KNOWN_ERC1155_ENCODING.tokenAddress, | ||||
|                     KNOWN_ERC1155_ENCODING.tokenIds, | ||||
|                     KNOWN_ERC1155_ENCODING.tokenValues, | ||||
|                     KNOWN_ERC1155_ENCODING.callbackData, | ||||
|                 ], | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it('should encode multiasset data', async () => { | ||||
|             expect( | ||||
|                 await libAssetData.encodeMultiAssetData.callAsync( | ||||
|                     KNOWN_MULTI_ASSET_ENCODING.amounts, | ||||
|                     KNOWN_MULTI_ASSET_ENCODING.nestedAssetData, | ||||
|                 ), | ||||
|             ).to.equal(KNOWN_MULTI_ASSET_ENCODING.assetData); | ||||
|         }); | ||||
|  | ||||
|         it('should decode multiasset data', async () => { | ||||
|             expect( | ||||
|                 await libAssetData.decodeMultiAssetData.callAsync(KNOWN_MULTI_ASSET_ENCODING.assetData), | ||||
|             ).to.deep.equal([ | ||||
|                 AssetProxyId.MultiAsset, | ||||
|                 KNOWN_MULTI_ASSET_ENCODING.amounts, | ||||
|                 KNOWN_MULTI_ASSET_ENCODING.nestedAssetData, | ||||
|             ]); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('getBalance', () => { | ||||
|         it('should query ERC20 balance by asset data', async () => { | ||||
|             const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); | ||||
|             expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal( | ||||
|                 erc20TokenTotalSupply, | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it('should return 0 if ERC20 token does not exist', async () => { | ||||
|             const assetData = assetDataUtils.encodeERC20AssetData(constants.NULL_ADDRESS); | ||||
|             const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData); | ||||
|             expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|  | ||||
|         it('should query ERC721 balance by asset data', async () => { | ||||
|             const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId); | ||||
|             expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal(1); | ||||
|         }); | ||||
|  | ||||
|         it('should return 0 if ERC721 token does not exist', async () => { | ||||
|             const assetData = assetDataUtils.encodeERC721AssetData(constants.NULL_ADDRESS, firstERC721TokenId); | ||||
|             const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData); | ||||
|             expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|  | ||||
|         it('should query ERC1155 balances by asset data', async () => { | ||||
|             const assetData = assetDataUtils.encodeERC1155AssetData( | ||||
|                 erc1155Token.address, | ||||
|                 [erc1155TokenId], | ||||
|                 [new BigNumber(1)], | ||||
|                 constants.NULL_BYTES, | ||||
|             ); | ||||
|             expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal(1); | ||||
|         }); | ||||
|  | ||||
|         it('should return 0 if ERC1155 token does not exist', async () => { | ||||
|             const assetData = assetDataUtils.encodeERC1155AssetData( | ||||
|                 constants.NULL_ADDRESS, | ||||
|                 [erc1155TokenId], | ||||
|                 [new BigNumber(1)], | ||||
|                 constants.NULL_BYTES, | ||||
|             ); | ||||
|             const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData); | ||||
|             expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|  | ||||
|         it('should query multi-asset batch balance by asset data', async () => { | ||||
|             const assetData = assetDataUtils.encodeMultiAssetData( | ||||
|                 [new BigNumber(1), new BigNumber(1)], | ||||
|                 [ | ||||
|                     assetDataUtils.encodeERC20AssetData(erc20Token.address), | ||||
|                     assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId), | ||||
|                 ], | ||||
|             ); | ||||
|             expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal( | ||||
|                 Math.min(erc20TokenTotalSupply.toNumber(), numberOfERC721Tokens), | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it('should return a balance of 0 if the assetData does not correspond to an AssetProxy contract', async () => { | ||||
|             const fakeAssetData = '0x01020304'; | ||||
|             const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, fakeAssetData); | ||||
|             expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|  | ||||
|         it('should return a balance of MAX_UINT256 if the the StaticCallProxy assetData contains data for a successful staticcall', async () => { | ||||
|             const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(1)); | ||||
|             const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); | ||||
|             const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData); | ||||
|             expect(balance).to.bignumber.equal(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); | ||||
|         }); | ||||
|  | ||||
|         it('should return a balance of 0 if the the StaticCallProxy assetData contains data for an unsuccessful staticcall', async () => { | ||||
|             const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(0)); | ||||
|             const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); | ||||
|             const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 expectedResultHash, | ||||
|             ); | ||||
|             const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData); | ||||
|             expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('getAssetProxyAllowance', () => { | ||||
|         it('should query ERC20 allowances by asset data', async () => { | ||||
|             const allowance = new BigNumber(1); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, { | ||||
|                 from: tokenOwnerAddress, | ||||
|             }); | ||||
|             const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); | ||||
|             expect( | ||||
|                 await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData), | ||||
|             ).to.bignumber.equal(allowance); | ||||
|         }); | ||||
|  | ||||
|         it('should query ERC721 approval by asset data', async () => { | ||||
|             await erc721Token.approve.awaitTransactionSuccessAsync(erc721Proxy.address, firstERC721TokenId, { | ||||
|                 from: tokenOwnerAddress, | ||||
|             }); | ||||
|             const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId); | ||||
|             expect( | ||||
|                 await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData), | ||||
|             ).to.bignumber.equal(1); | ||||
|         }); | ||||
|  | ||||
|         it('should query ERC721 approvalForAll by assetData', async () => { | ||||
|             await erc721Token.setApprovalForAll.awaitTransactionSuccessAsync(erc721Proxy.address, true, { | ||||
|                 from: tokenOwnerAddress, | ||||
|             }); | ||||
|             const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId); | ||||
|             expect( | ||||
|                 await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData), | ||||
|             ).to.bignumber.equal(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); | ||||
|         }); | ||||
|  | ||||
|         it('should query ERC1155 allowances by asset data', async () => { | ||||
|             await erc1155Token.setApprovalForAll.awaitTransactionSuccessAsync(erc1155Proxy.address, true, { | ||||
|                 from: tokenOwnerAddress, | ||||
|             }); | ||||
|             const assetData = assetDataUtils.encodeERC1155AssetData( | ||||
|                 erc1155Token.address, | ||||
|                 [erc1155TokenId], | ||||
|                 [new BigNumber(1)], | ||||
|                 constants.NULL_BYTES, | ||||
|             ); | ||||
|             expect( | ||||
|                 await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData), | ||||
|             ).to.bignumber.equal(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); | ||||
|         }); | ||||
|  | ||||
|         it('should query multi-asset allowances by asset data', async () => { | ||||
|             const allowance = new BigNumber(1); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, { | ||||
|                 from: tokenOwnerAddress, | ||||
|             }); | ||||
|             await erc721Token.approve.awaitTransactionSuccessAsync(erc721Proxy.address, firstERC721TokenId, { | ||||
|                 from: tokenOwnerAddress, | ||||
|             }); | ||||
|             const assetData = assetDataUtils.encodeMultiAssetData( | ||||
|                 [new BigNumber(1), new BigNumber(1)], | ||||
|                 [ | ||||
|                     assetDataUtils.encodeERC20AssetData(erc20Token.address), | ||||
|                     assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId), | ||||
|                 ], | ||||
|             ); | ||||
|             expect( | ||||
|                 await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData), | ||||
|             ).to.bignumber.equal(1); | ||||
|             return; | ||||
|         }); | ||||
|  | ||||
|         it('should return an allowance of 0 if the assetData does not correspond to an AssetProxy contract', async () => { | ||||
|             const fakeAssetData = '0x01020304'; | ||||
|             const allowance = await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, fakeAssetData); | ||||
|             expect(allowance).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|  | ||||
|         it('should return an allowance of MAX_UINT256 for any staticCallAssetData', async () => { | ||||
|             const staticCallData = AssetProxyId.StaticCall; | ||||
|             const assetData = assetDataUtils.encodeStaticCallAssetData( | ||||
|                 staticCallTarget.address, | ||||
|                 staticCallData, | ||||
|                 constants.KECCAK256_NULL, | ||||
|             ); | ||||
|             const allowance = await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData); | ||||
|             expect(allowance).to.bignumber.equal(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('getBatchBalances', () => { | ||||
|         it('should query balances for a batch of asset data strings', async () => { | ||||
|             const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); | ||||
|             const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId); | ||||
|             expect( | ||||
|                 await libAssetData.getBatchBalances.callAsync(tokenOwnerAddress, [erc20AssetData, erc721AssetData]), | ||||
|             ).to.deep.equal([new BigNumber(erc20TokenTotalSupply), new BigNumber(1)]); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('getERC721TokenOwner', async () => { | ||||
|         it('should return the null address when tokenId is not owned', async () => { | ||||
|             const nonexistentTokenId = new BigNumber(1234567890); | ||||
|             expect( | ||||
|                 await libAssetData.getERC721TokenOwner.callAsync(erc721Token.address, nonexistentTokenId), | ||||
|             ).to.be.equal(constants.NULL_ADDRESS); | ||||
|         }); | ||||
|         it('should return the owner address when tokenId is owned', async () => { | ||||
|             expect( | ||||
|                 await libAssetData.getERC721TokenOwner.callAsync(erc721Token.address, firstERC721TokenId), | ||||
|             ).to.be.equal(tokenOwnerAddress); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('getBalanceAndAllowance', () => { | ||||
|         it('should query balance and allowance together, from asset data', async () => { | ||||
|             const allowance = new BigNumber(1); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, { | ||||
|                 from: tokenOwnerAddress, | ||||
|             }); | ||||
|             const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); | ||||
|             expect( | ||||
|                 await libAssetData.getBalanceAndAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData), | ||||
|             ).to.deep.equal([new BigNumber(erc20TokenTotalSupply), allowance]); | ||||
|         }); | ||||
|     }); | ||||
|     describe('getBatchBalancesAndAllowances', () => { | ||||
|         it('should query balances and allowances together, from an asset data array', async () => { | ||||
|             const allowance = new BigNumber(1); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, { | ||||
|                 from: tokenOwnerAddress, | ||||
|             }); | ||||
|             const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); | ||||
|             expect( | ||||
|                 await libAssetData.getBatchBalancesAndAssetProxyAllowances.callAsync(tokenOwnerAddress, [assetData]), | ||||
|             ).to.deep.equal([[new BigNumber(erc20TokenTotalSupply)], [allowance]]); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('getBatchAssetProxyAllowances', () => { | ||||
|         it('should query allowances for a batch of asset data strings', async () => { | ||||
|             const allowance = new BigNumber(1); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, { | ||||
|                 from: tokenOwnerAddress, | ||||
|             }); | ||||
|             await erc721Token.approve.awaitTransactionSuccessAsync(erc721Proxy.address, firstERC721TokenId, { | ||||
|                 from: tokenOwnerAddress, | ||||
|             }); | ||||
|             const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); | ||||
|             const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId); | ||||
|             expect( | ||||
|                 await libAssetData.getBatchAssetProxyAllowances.callAsync(tokenOwnerAddress, [ | ||||
|                     erc20AssetData, | ||||
|                     erc721AssetData, | ||||
|                 ]), | ||||
|             ).to.deep.equal([new BigNumber(1), new BigNumber(1)]); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| // tslint:disable:max-file-line-count | ||||
							
								
								
									
										140
									
								
								contracts/dev-utils/test/lib_transaction_decoder.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								contracts/dev-utils/test/lib_transaction_decoder.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| import { IExchangeContract } from '@0x/contracts-exchange'; | ||||
| import { chaiSetup, constants, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils'; | ||||
| import { BlockchainLifecycle } from '@0x/dev-utils'; | ||||
| import { BigNumber } from '@0x/utils'; | ||||
| import * as chai from 'chai'; | ||||
|  | ||||
| import { artifacts, LibTransactionDecoderContract } from '../src'; | ||||
|  | ||||
| chaiSetup.configure(); | ||||
| const expect = chai.expect; | ||||
| const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); | ||||
|  | ||||
| const order = { | ||||
|     makerAddress: '0xe36ea790bc9d7ab70c55260c66d52b1eca985f84', | ||||
|     takerAddress: '0x0000000000000000000000000000000000000000', | ||||
|     feeRecipientAddress: '0x78dc5d2d739606d31509c31d654056a45185ecb6', | ||||
|     senderAddress: '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb', | ||||
|     makerAssetAmount: new BigNumber('100000000000000000000'), | ||||
|     takerAssetAmount: new BigNumber('200000000000000000000'), | ||||
|     makerFee: new BigNumber('1000000000000000000'), | ||||
|     takerFee: new BigNumber('1000000000000000000'), | ||||
|     expirationTimeSeconds: new BigNumber('1552396423'), | ||||
|     salt: new BigNumber('66097384406870180066678463045003379626790660770396923976862707230261946348951'), | ||||
|     makerAssetData: '0xf47261b000000000000000000000000034d402f14d58e001d8efbe6585051bf9706aa064', | ||||
|     takerAssetData: '0xf47261b000000000000000000000000025b8fe1de9daf8ba351890744ff28cf7dfa8f5e3', | ||||
| }; | ||||
| const takerAssetFillAmount = new BigNumber('100000000000000000000'); | ||||
| const signature = | ||||
|     '0x1ce8e3c600d933423172b5021158a6be2e818613ff8e762d70ef490c752fd98a626a215f09f169668990414de75a53da221c294a3002f796d004827258b641876e03'; | ||||
|  | ||||
| describe('LibTransactionDecoder', () => { | ||||
|     let libTxDecoder: LibTransactionDecoderContract; | ||||
|     const exchangeInterface = new IExchangeContract(constants.NULL_ADDRESS, provider, txDefaults); | ||||
|     before(async () => { | ||||
|         await blockchainLifecycle.startAsync(); | ||||
|         libTxDecoder = await LibTransactionDecoderContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.LibTransactionDecoder, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|     }); | ||||
|     after(async () => { | ||||
|         await blockchainLifecycle.revertAsync(); | ||||
|     }); | ||||
|  | ||||
|     it('should decode an Exchange.batchCancelOrders() transaction', async () => { | ||||
|         const input = exchangeInterface.batchCancelOrders.getABIEncodedTransactionData([order, order]); | ||||
|         expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([ | ||||
|             'batchCancelOrders', | ||||
|             [order, order], | ||||
|             [], | ||||
|             [], | ||||
|         ]); | ||||
|     }); | ||||
|  | ||||
|     for (const func of ['batchFillOrders', 'batchFillOrdersNoThrow', 'batchFillOrKillOrders']) { | ||||
|         const input = (exchangeInterface as any)[func].getABIEncodedTransactionData( | ||||
|             [order, order], | ||||
|             [takerAssetFillAmount, takerAssetFillAmount], | ||||
|             [signature, signature], | ||||
|         ); | ||||
|         it(`should decode an Exchange.${func}() transaction`, async () => { | ||||
|             expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([ | ||||
|                 func, | ||||
|                 [order, order], | ||||
|                 [takerAssetFillAmount, takerAssetFillAmount], | ||||
|                 [signature, signature], | ||||
|             ]); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     it('should decode an Exchange.cancelOrder() transaction', async () => { | ||||
|         const input = exchangeInterface.cancelOrder.getABIEncodedTransactionData(order); | ||||
|         expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([ | ||||
|             'cancelOrder', | ||||
|             [order], | ||||
|             [], | ||||
|             [], | ||||
|         ]); | ||||
|     }); | ||||
|  | ||||
|     for (const func of ['fillOrder', 'fillOrderNoThrow', 'fillOrKillOrder']) { | ||||
|         const input = (exchangeInterface as any)[func].getABIEncodedTransactionData( | ||||
|             order, | ||||
|             takerAssetFillAmount, | ||||
|             signature, | ||||
|         ); | ||||
|         it(`should decode an Exchange.${func}() transaction`, async () => { | ||||
|             expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([ | ||||
|                 func, | ||||
|                 [order], | ||||
|                 [takerAssetFillAmount], | ||||
|                 [signature], | ||||
|             ]); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     for (const func of ['marketBuyOrders', 'marketBuyOrdersNoThrow', 'marketSellOrders', 'marketSellOrdersNoThrow']) { | ||||
|         const input = (exchangeInterface as any)[func].getABIEncodedTransactionData( | ||||
|             [order, order], | ||||
|             takerAssetFillAmount, | ||||
|             [signature, signature], | ||||
|         ); | ||||
|         it(`should decode an Exchange.${func}() transaction`, async () => { | ||||
|             expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([ | ||||
|                 func, | ||||
|                 [order, order], | ||||
|                 [takerAssetFillAmount], | ||||
|                 [signature, signature], | ||||
|             ]); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     it('should decode an Exchange.matchOrders() transaction', async () => { | ||||
|         const complementaryOrder = { | ||||
|             ...order, | ||||
|             makerAddress: order.takerAddress, | ||||
|             takerAddress: order.makerAddress, | ||||
|             makerAssetData: order.takerAssetData, | ||||
|             takerAssetData: order.makerAssetData, | ||||
|             makerAssetAmount: order.takerAssetAmount, | ||||
|             takerAssetAmount: order.makerAssetAmount, | ||||
|             makerFee: order.takerFee, | ||||
|             takerFee: order.makerFee, | ||||
|         }; | ||||
|         const input = exchangeInterface.matchOrders.getABIEncodedTransactionData( | ||||
|             order, | ||||
|             complementaryOrder, | ||||
|             signature, | ||||
|             signature, | ||||
|         ); | ||||
|         expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([ | ||||
|             'matchOrders', | ||||
|             [order, complementaryOrder], | ||||
|             [order.takerAssetAmount, complementaryOrder.takerAssetAmount], | ||||
|             [signature, signature], | ||||
|         ]); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										445
									
								
								contracts/dev-utils/test/order_validation_utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										445
									
								
								contracts/dev-utils/test/order_validation_utils.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,445 @@ | ||||
| import { | ||||
|     artifacts as proxyArtifacts, | ||||
|     ERC20ProxyContract, | ||||
|     ERC20Wrapper, | ||||
|     ERC721ProxyContract, | ||||
|     ERC721Wrapper, | ||||
|     MultiAssetProxyContract, | ||||
| } from '@0x/contracts-asset-proxy'; | ||||
| import { DummyERC20TokenContract } from '@0x/contracts-erc20'; | ||||
| import { DummyERC721TokenContract } from '@0x/contracts-erc721'; | ||||
| import { artifacts as exchangeArtifacts, ExchangeContract, ExchangeWrapper } from '@0x/contracts-exchange'; | ||||
| import { | ||||
|     chaiSetup, | ||||
|     constants, | ||||
|     OrderFactory, | ||||
|     OrderStatus, | ||||
|     provider, | ||||
|     txDefaults, | ||||
|     web3Wrapper, | ||||
| } from '@0x/contracts-test-utils'; | ||||
| import { BlockchainLifecycle } from '@0x/dev-utils'; | ||||
| import { assetDataUtils, orderHashUtils } from '@0x/order-utils'; | ||||
| import { SignedOrder } from '@0x/types'; | ||||
| import { BigNumber } from '@0x/utils'; | ||||
| import * as chai from 'chai'; | ||||
|  | ||||
| import { artifacts, DevUtilsContract } from '../src'; | ||||
|  | ||||
| chaiSetup.configure(); | ||||
| const expect = chai.expect; | ||||
| const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); | ||||
|  | ||||
| describe('OrderValidationUtils', () => { | ||||
|     let makerAddress: string; | ||||
|     let takerAddress: string; | ||||
|     let owner: string; | ||||
|     let erc20AssetData: string; | ||||
|     let erc20AssetData2: string; | ||||
|     let erc721AssetData: string; | ||||
|     let zrxAssetData: string; | ||||
|  | ||||
|     let erc20Token: DummyERC20TokenContract; | ||||
|     let erc20Token2: DummyERC20TokenContract; | ||||
|     let zrxToken: DummyERC20TokenContract; | ||||
|     let erc721Token: DummyERC721TokenContract; | ||||
|     let exchange: ExchangeContract; | ||||
|     let devUtils: DevUtilsContract; | ||||
|     let erc20Proxy: ERC20ProxyContract; | ||||
|     let erc721Proxy: ERC721ProxyContract; | ||||
|     let multiAssetProxy: MultiAssetProxyContract; | ||||
|  | ||||
|     let signedOrder: SignedOrder; | ||||
|     let orderFactory: OrderFactory; | ||||
|  | ||||
|     const tokenId = new BigNumber(123456789); | ||||
|  | ||||
|     before(async () => { | ||||
|         await blockchainLifecycle.startAsync(); | ||||
|     }); | ||||
|     after(async () => { | ||||
|         await blockchainLifecycle.revertAsync(); | ||||
|     }); | ||||
|  | ||||
|     before(async () => { | ||||
|         const accounts = await web3Wrapper.getAvailableAddressesAsync(); | ||||
|         const usedAddresses = ([owner, makerAddress, takerAddress] = accounts.slice(0, 3)); | ||||
|  | ||||
|         const erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner); | ||||
|         const erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner); | ||||
|  | ||||
|         const numDummyErc20ToDeploy = 3; | ||||
|         [erc20Token, zrxToken, erc20Token2] = await erc20Wrapper.deployDummyTokensAsync( | ||||
|             numDummyErc20ToDeploy, | ||||
|             constants.DUMMY_TOKEN_DECIMALS, | ||||
|         ); | ||||
|         erc20Proxy = await erc20Wrapper.deployProxyAsync(); | ||||
|  | ||||
|         [erc721Token] = await erc721Wrapper.deployDummyTokensAsync(); | ||||
|         erc721Proxy = await erc721Wrapper.deployProxyAsync(); | ||||
|  | ||||
|         zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address); | ||||
|         exchange = await ExchangeContract.deployFrom0xArtifactAsync( | ||||
|             exchangeArtifacts.Exchange, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             zrxAssetData, | ||||
|         ); | ||||
|  | ||||
|         multiAssetProxy = await MultiAssetProxyContract.deployFrom0xArtifactAsync( | ||||
|             proxyArtifacts.MultiAssetProxy, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         const exchangeWrapper = new ExchangeWrapper(exchange, provider); | ||||
|         await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner); | ||||
|         await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner); | ||||
|         await exchangeWrapper.registerAssetProxyAsync(multiAssetProxy.address, owner); | ||||
|         await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(exchange.address, { from: owner }); | ||||
|         await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(exchange.address, { from: owner }); | ||||
|  | ||||
|         devUtils = await DevUtilsContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.DevUtils, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             exchange.address, | ||||
|             zrxAssetData, | ||||
|         ); | ||||
|  | ||||
|         erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); | ||||
|         erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20Token2.address); | ||||
|         erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, tokenId); | ||||
|         const defaultOrderParams = { | ||||
|             ...constants.STATIC_ORDER_PARAMS, | ||||
|             exchangeAddress: exchange.address, | ||||
|             makerAddress, | ||||
|             feeRecipientAddress: constants.NULL_ADDRESS, | ||||
|             makerAssetData: erc20AssetData, | ||||
|             takerAssetData: erc20AssetData2, | ||||
|         }; | ||||
|         const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)]; | ||||
|         orderFactory = new OrderFactory(privateKey, defaultOrderParams); | ||||
|     }); | ||||
|  | ||||
|     beforeEach(async () => { | ||||
|         await blockchainLifecycle.startAsync(); | ||||
|     }); | ||||
|     afterEach(async () => { | ||||
|         await blockchainLifecycle.revertAsync(); | ||||
|     }); | ||||
|  | ||||
|     describe('getTransferableAssetAmount', () => { | ||||
|         it('should return the balance when balance < allowance', async () => { | ||||
|             const balance = new BigNumber(123); | ||||
|             const allowance = new BigNumber(456); | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, balance); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const transferableAmount = await devUtils.getTransferableAssetAmount.callAsync( | ||||
|                 makerAddress, | ||||
|                 erc20AssetData, | ||||
|             ); | ||||
|             expect(transferableAmount).to.bignumber.equal(balance); | ||||
|         }); | ||||
|         it('should return the allowance when allowance < balance', async () => { | ||||
|             const balance = new BigNumber(456); | ||||
|             const allowance = new BigNumber(123); | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, balance); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const transferableAmount = await devUtils.getTransferableAssetAmount.callAsync( | ||||
|                 makerAddress, | ||||
|                 erc20AssetData, | ||||
|             ); | ||||
|             expect(transferableAmount).to.bignumber.equal(allowance); | ||||
|         }); | ||||
|         it('should return the correct transferable amount for multiAssetData', async () => { | ||||
|             const multiAssetData = assetDataUtils.encodeMultiAssetData( | ||||
|                 [new BigNumber(1), new BigNumber(1)], | ||||
|                 [erc20AssetData, erc20AssetData2], | ||||
|             ); | ||||
|             const transferableAmount1 = new BigNumber(10); | ||||
|             const transferableAmount2 = new BigNumber(5); | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, transferableAmount1); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, transferableAmount1, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             await erc20Token2.setBalance.awaitTransactionSuccessAsync(makerAddress, transferableAmount2); | ||||
|             await erc20Token2.approve.awaitTransactionSuccessAsync(erc20Proxy.address, transferableAmount2, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const transferableAmount = await devUtils.getTransferableAssetAmount.callAsync( | ||||
|                 makerAddress, | ||||
|                 multiAssetData, | ||||
|             ); | ||||
|             expect(transferableAmount).to.bignumber.equal(transferableAmount2); | ||||
|         }); | ||||
|     }); | ||||
|     describe('getOrderRelevantState', () => { | ||||
|         beforeEach(async () => { | ||||
|             signedOrder = await orderFactory.newSignedOrderAsync(); | ||||
|         }); | ||||
|         it('should return the correct orderInfo when the order is valid', async () => { | ||||
|             const [orderInfo] = await devUtils.getOrderRelevantState.callAsync(signedOrder, signedOrder.signature); | ||||
|             expect(orderInfo.orderHash).to.equal(orderHashUtils.getOrderHashHex(signedOrder)); | ||||
|             expect(orderInfo.orderStatus).to.equal(OrderStatus.Fillable); | ||||
|             expect(orderInfo.orderTakerAssetFilledAmount).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|         it('should return isValidSignature=true when the signature is valid', async () => { | ||||
|             const [, , isValidSignature] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(isValidSignature).to.equal(true); | ||||
|         }); | ||||
|         it('should return isValidSignature=false when the signature is invalid', async () => { | ||||
|             const invalidSignature = '0x01'; | ||||
|             const [, , isValidSignature] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 invalidSignature, | ||||
|             ); | ||||
|             expect(isValidSignature).to.equal(false); | ||||
|         }); | ||||
|         it('should return a fillableTakerAssetAmount of 0 when balances or allowances are insufficient', async () => { | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|         it('should return a fillableTakerAssetAmount of 0 when fee balances/allowances are insufficient', async () => { | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|         it('should return a fillableTakerAssetAmount of 0 when balances/allowances of one asset within a multiAssetData are insufficient', async () => { | ||||
|             const multiAssetData = assetDataUtils.encodeMultiAssetData( | ||||
|                 [new BigNumber(1), new BigNumber(1)], | ||||
|                 [erc20AssetData, erc20AssetData2], | ||||
|             ); | ||||
|             signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: multiAssetData }); | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|         it('should return the correct fillableTakerAssetAmount when fee balances/allowances are partially sufficient', async () => { | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const divisor = 4; | ||||
|             await zrxToken.setBalance.awaitTransactionSuccessAsync( | ||||
|                 makerAddress, | ||||
|                 signedOrder.makerFee.dividedToIntegerBy(divisor), | ||||
|             ); | ||||
|             await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal( | ||||
|                 signedOrder.takerAssetAmount.dividedToIntegerBy(divisor), | ||||
|             ); | ||||
|         }); | ||||
|         it('should return the correct fillableTakerAssetAmount when non-fee balances/allowances are partially sufficient', async () => { | ||||
|             const divisor = 4; | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync( | ||||
|                 makerAddress, | ||||
|                 signedOrder.makerAssetAmount.dividedToIntegerBy(divisor), | ||||
|             ); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee); | ||||
|             await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal( | ||||
|                 signedOrder.takerAssetAmount.dividedToIntegerBy(divisor), | ||||
|             ); | ||||
|         }); | ||||
|         it('should return the correct fillableTakerAssetAmount when balances/allowances of one asset within a multiAssetData are partially sufficient', async () => { | ||||
|             const multiAssetData = assetDataUtils.encodeMultiAssetData( | ||||
|                 [new BigNumber(1), new BigNumber(1)], | ||||
|                 [erc20AssetData, erc20AssetData2], | ||||
|             ); | ||||
|             signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: multiAssetData }); | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee); | ||||
|             await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const divisor = 4; | ||||
|             await erc20Token2.setBalance.awaitTransactionSuccessAsync( | ||||
|                 makerAddress, | ||||
|                 signedOrder.makerAssetAmount.dividedToIntegerBy(divisor), | ||||
|             ); | ||||
|             await erc20Token2.approve.awaitTransactionSuccessAsync( | ||||
|                 erc20Proxy.address, | ||||
|                 signedOrder.makerAssetAmount.dividedToIntegerBy(divisor), | ||||
|                 { | ||||
|                     from: makerAddress, | ||||
|                 }, | ||||
|             ); | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal( | ||||
|                 signedOrder.takerAssetAmount.dividedToIntegerBy(divisor), | ||||
|             ); | ||||
|         }); | ||||
|         it('should return a fillableTakerAssetAmount of 0 when non-fee balances/allowances are insufficient', async () => { | ||||
|             await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee); | ||||
|             await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|         }); | ||||
|         it('should return a fillableTakerAssetAmount equal to the takerAssetAmount when the order is unfilled and balances/allowances are sufficient', async () => { | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee); | ||||
|             await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal(signedOrder.takerAssetAmount); | ||||
|         }); | ||||
|         it('should return the correct fillableTakerAssetAmount when balances/allowances are partially sufficient and makerAsset=makerFeeAsset', async () => { | ||||
|             signedOrder = await orderFactory.newSignedOrderAsync({ | ||||
|                 makerAssetData: zrxAssetData, | ||||
|                 makerAssetAmount: new BigNumber(10), | ||||
|                 takerAssetAmount: new BigNumber(20), | ||||
|                 makerFee: new BigNumber(40), | ||||
|             }); | ||||
|             const transferableMakerAssetAmount = new BigNumber(10); | ||||
|             await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, transferableMakerAssetAmount); | ||||
|             await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, transferableMakerAssetAmount, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const expectedFillableTakerAssetAmount = transferableMakerAssetAmount | ||||
|                 .times(signedOrder.takerAssetAmount) | ||||
|                 .dividedToIntegerBy(signedOrder.makerAssetAmount.plus(signedOrder.makerFee)); | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal(expectedFillableTakerAssetAmount); | ||||
|         }); | ||||
|         it('should return the correct fillabeTakerassetAmount when makerAsset balances/allowances are sufficient and there are no maker fees', async () => { | ||||
|             signedOrder = await orderFactory.newSignedOrderAsync({ makerFee: constants.ZERO_AMOUNT }); | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal(signedOrder.takerAssetAmount); | ||||
|         }); | ||||
|         it('should return a fillableTakerAssetAmount when the remaining takerAssetAmount is less than the transferable amount', async () => { | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee); | ||||
|             await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             await erc20Token2.setBalance.awaitTransactionSuccessAsync(takerAddress, signedOrder.takerAssetAmount); | ||||
|             await erc20Token2.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.takerAssetAmount, { | ||||
|                 from: takerAddress, | ||||
|             }); | ||||
|             await zrxToken.setBalance.awaitTransactionSuccessAsync(takerAddress, signedOrder.takerFee); | ||||
|  | ||||
|             await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.takerFee, { | ||||
|                 from: takerAddress, | ||||
|             }); | ||||
|             const takerAssetFillAmount = signedOrder.takerAssetAmount.dividedToIntegerBy(4); | ||||
|             await exchange.fillOrder.awaitTransactionSuccessAsync( | ||||
|                 signedOrder, | ||||
|                 takerAssetFillAmount, | ||||
|                 signedOrder.signature, | ||||
|                 { from: takerAddress }, | ||||
|             ); | ||||
|             const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync( | ||||
|                 signedOrder, | ||||
|                 signedOrder.signature, | ||||
|             ); | ||||
|             expect(fillableTakerAssetAmount).to.bignumber.equal( | ||||
|                 signedOrder.takerAssetAmount.minus(takerAssetFillAmount), | ||||
|             ); | ||||
|         }); | ||||
|     }); | ||||
|     describe('getOrderRelevantStates', async () => { | ||||
|         it('should return the correct information for multiple orders', async () => { | ||||
|             await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount); | ||||
|             await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee); | ||||
|             await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, { | ||||
|                 from: makerAddress, | ||||
|             }); | ||||
|             const signedOrder2 = await orderFactory.newSignedOrderAsync({ makerAssetData: erc721AssetData }); | ||||
|             const invalidSignature = '0x01'; | ||||
|             await exchange.cancelOrder.awaitTransactionSuccessAsync(signedOrder2, { from: makerAddress }); | ||||
|             const [ | ||||
|                 ordersInfo, | ||||
|                 fillableTakerAssetAmounts, | ||||
|                 isValidSignature, | ||||
|             ] = await devUtils.getOrderRelevantStates.callAsync( | ||||
|                 [signedOrder, signedOrder2], | ||||
|                 [signedOrder.signature, invalidSignature], | ||||
|             ); | ||||
|             expect(ordersInfo[0].orderHash).to.equal(orderHashUtils.getOrderHashHex(signedOrder)); | ||||
|             expect(ordersInfo[1].orderHash).to.equal(orderHashUtils.getOrderHashHex(signedOrder2)); | ||||
|             expect(ordersInfo[0].orderStatus).to.equal(OrderStatus.Fillable); | ||||
|             expect(ordersInfo[1].orderStatus).to.equal(OrderStatus.Cancelled); | ||||
|             expect(ordersInfo[0].orderTakerAssetFilledAmount).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|             expect(ordersInfo[1].orderTakerAssetFilledAmount).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|             expect(fillableTakerAssetAmounts[0]).to.bignumber.equal(signedOrder.takerAssetAmount); | ||||
|             expect(fillableTakerAssetAmounts[1]).to.bignumber.equal(constants.ZERO_AMOUNT); | ||||
|             expect(isValidSignature[0]).to.equal(true); | ||||
|             expect(isValidSignature[1]).to.equal(false); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| // tslint:disable:max-file-line-count | ||||
							
								
								
									
										12
									
								
								contracts/dev-utils/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								contracts/dev-utils/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|     "extends": "../../tsconfig", | ||||
|     "compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true }, | ||||
|     "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"], | ||||
|     "files": [ | ||||
|         "generated-artifacts/DevUtils.json", | ||||
|         "generated-artifacts/LibAssetData.json", | ||||
|         "generated-artifacts/LibTransactionDecoder.json", | ||||
|         "generated-artifacts/EthBalanceChecker.json" | ||||
|     ], | ||||
|     "exclude": ["./deploy/solc/solc_bin"] | ||||
| } | ||||
							
								
								
									
										6
									
								
								contracts/dev-utils/tslint.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								contracts/dev-utils/tslint.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| { | ||||
|     "extends": ["@0x/tslint-config"], | ||||
|     "rules": { | ||||
|         "custom-no-magic-numbers": false | ||||
|     } | ||||
| } | ||||
| @@ -1,4 +1,95 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1565296576, | ||||
|         "version": "1.1.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.1.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies.", | ||||
|                 "pr": 1995 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1564604963 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563957393, | ||||
|         "version": "1.1.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563193019, | ||||
|         "version": "1.1.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563047529, | ||||
|         "version": "1.1.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563006338, | ||||
|         "version": "1.1.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1558712885, | ||||
|         "version": "1.1.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557961111, | ||||
|         "version": "1.1.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.1.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1557799313 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557507213, | ||||
|         "version": "1.1.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.1.1", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,46 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.1.12 - _August 8, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.11 - _July 31, 2019_ | ||||
|  | ||||
|     * Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies. (#1995) | ||||
|  | ||||
| ## v1.1.10 - _July 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.9 - _July 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.8 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.7 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.6 - _May 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.5 - _May 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.4 - _May 14, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.2 - _May 10, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.1 - _April 11, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|     "artifactsDir": "generated-artifacts", | ||||
|     "contractsDir": "contracts", | ||||
|     "useDockerisedSolc": true, | ||||
|     "useDockerisedSolc": false, | ||||
|     "compilerSettings": { | ||||
|         "evmVersion": "constantinople", | ||||
|         "optimizer": { "enabled": true, "runs": 1000000 }, | ||||
| @@ -9,6 +9,7 @@ | ||||
|             "*": { | ||||
|                 "*": [ | ||||
|                     "abi", | ||||
|                     "devdoc", | ||||
|                     "evm.bytecode.object", | ||||
|                     "evm.bytecode.sourceMap", | ||||
|                     "evm.deployedBytecode.object", | ||||
|   | ||||
| @@ -63,6 +63,32 @@ contract ERC1155Mintable is | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev creates a new token | ||||
|     /// @param type_ of token | ||||
|     /// @param uri URI of token | ||||
|     function createWithType( | ||||
|         uint256 type_, | ||||
|         string calldata uri | ||||
|     ) | ||||
|         external | ||||
|     { | ||||
|         // This will allow restricted access to creators. | ||||
|         creators[type_] = msg.sender; | ||||
|  | ||||
|         // emit a Transfer event with Create semantic to help with discovery. | ||||
|         emit TransferSingle( | ||||
|             msg.sender, | ||||
|             address(0x0), | ||||
|             address(0x0), | ||||
|             type_, | ||||
|             0 | ||||
|         ); | ||||
|  | ||||
|         if (bytes(uri).length > 0) { | ||||
|             emit URI(uri, type_); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev mints fungible tokens | ||||
|     /// @param id token type | ||||
|     /// @param to beneficiaries of minted tokens | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc1155", | ||||
|     "version": "1.1.1", | ||||
|     "version": "1.1.12", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -47,19 +47,20 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^2.0.9", | ||||
|         "@0x/contracts-gen": "^1.0.8", | ||||
|         "@0x/dev-utils": "^2.2.1", | ||||
|         "@0x/sol-compiler": "^3.1.6", | ||||
|         "@0x/abi-gen": "^4.1.0", | ||||
|         "@0x/contracts-gen": "^1.0.13", | ||||
|         "@0x/dev-utils": "^2.3.0", | ||||
|         "@0x/sol-compiler": "^3.1.12", | ||||
|         "@0x/tslint-config": "^3.0.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^4.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
|         "solhint": "^1.4.1", | ||||
| @@ -67,14 +68,14 @@ | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^5.0.5", | ||||
|         "@0x/contracts-test-utils": "^3.1.2", | ||||
|         "@0x/contracts-utils": "^3.1.1", | ||||
|         "@0x/types": "^2.2.2", | ||||
|         "@0x/typescript-typings": "^4.2.2", | ||||
|         "@0x/utils": "^4.3.1", | ||||
|         "@0x/web3-wrapper": "^6.0.5", | ||||
|         "ethereum-types": "^2.1.2", | ||||
|         "@0x/base-contract": "^5.3.1", | ||||
|         "@0x/contracts-test-utils": "^3.1.13", | ||||
|         "@0x/contracts-utils": "^3.2.1", | ||||
|         "@0x/types": "^2.4.1", | ||||
|         "@0x/typescript-typings": "^4.2.4", | ||||
|         "@0x/utils": "^4.5.0", | ||||
|         "@0x/web3-wrapper": "^6.0.10", | ||||
|         "ethereum-types": "^2.1.4", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -60,11 +60,13 @@ describe('ERC1155Token', () => { | ||||
|             artifacts.ERC1155Mintable, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         erc1155Receiver = await DummyERC1155ReceiverContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.DummyERC1155Receiver, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         receiver = erc1155Receiver.address; | ||||
|         // create wrapper & mint erc1155 tokens | ||||
|   | ||||
| @@ -1,4 +1,95 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1565296576, | ||||
|         "version": "2.2.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.2.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies.", | ||||
|                 "pr": 1995 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1564604963 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563957393, | ||||
|         "version": "2.2.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563193019, | ||||
|         "version": "2.2.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563047529, | ||||
|         "version": "2.2.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563006338, | ||||
|         "version": "2.2.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1558712885, | ||||
|         "version": "2.2.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557961111, | ||||
|         "version": "2.2.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.2.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1557799313 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557507213, | ||||
|         "version": "2.2.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.2.0", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,46 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v2.2.11 - _August 8, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.10 - _July 31, 2019_ | ||||
|  | ||||
|     * Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies. (#1995) | ||||
|  | ||||
| ## v2.2.9 - _July 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.8 - _July 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.7 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.6 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.5 - _May 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.4 - _May 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.3 - _May 14, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.1 - _May 10, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.2.0 - _April 11, 2019_ | ||||
|  | ||||
|     * Added UntransferrableDummyERC20Token (#1714) | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|     "artifactsDir": "./generated-artifacts", | ||||
|     "contractsDir": "./contracts", | ||||
|     "useDockerisedSolc": true, | ||||
|     "useDockerisedSolc": false, | ||||
|     "isOfflineMode": false, | ||||
|     "compilerSettings": { | ||||
|         "evmVersion": "constantinople", | ||||
| @@ -14,10 +14,12 @@ | ||||
|             "*": { | ||||
|                 "*": [ | ||||
|                     "abi", | ||||
|                     "devdoc", | ||||
|                     "evm.bytecode.object", | ||||
|                     "evm.bytecode.sourceMap", | ||||
|                     "evm.deployedBytecode.object", | ||||
|                     "evm.deployedBytecode.sourceMap" | ||||
|                     "evm.deployedBytecode.sourceMap", | ||||
|                     "devdoc" | ||||
|                 ] | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc20", | ||||
|     "version": "2.2.0", | ||||
|     "version": "2.2.11", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -47,20 +47,21 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^2.0.9", | ||||
|         "@0x/contracts-gen": "^1.0.8", | ||||
|         "@0x/contracts-test-utils": "^3.1.2", | ||||
|         "@0x/dev-utils": "^2.2.1", | ||||
|         "@0x/sol-compiler": "^3.1.6", | ||||
|         "@0x/abi-gen": "^4.1.0", | ||||
|         "@0x/contracts-gen": "^1.0.13", | ||||
|         "@0x/contracts-test-utils": "^3.1.13", | ||||
|         "@0x/dev-utils": "^2.3.0", | ||||
|         "@0x/sol-compiler": "^3.1.12", | ||||
|         "@0x/tslint-config": "^3.0.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^4.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
|         "solhint": "^1.4.1", | ||||
| @@ -68,14 +69,13 @@ | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^5.0.5", | ||||
|         "@0x/contracts-exchange-libs": "^2.1.1", | ||||
|         "@0x/contracts-utils": "^3.1.1", | ||||
|         "@0x/types": "^2.2.2", | ||||
|         "@0x/typescript-typings": "^4.2.2", | ||||
|         "@0x/utils": "^4.3.1", | ||||
|         "@0x/web3-wrapper": "^6.0.5", | ||||
|         "ethereum-types": "^2.1.2", | ||||
|         "@0x/base-contract": "^5.3.1", | ||||
|         "@0x/contracts-utils": "^3.2.1", | ||||
|         "@0x/types": "^2.4.1", | ||||
|         "@0x/typescript-typings": "^4.2.4", | ||||
|         "@0x/utils": "^4.5.0", | ||||
|         "@0x/web3-wrapper": "^6.0.10", | ||||
|         "ethereum-types": "^2.1.4", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -37,6 +37,7 @@ describe('UnlimitedAllowanceToken', () => { | ||||
|             artifacts.DummyERC20Token, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             constants.DUMMY_TOKEN_NAME, | ||||
|             constants.DUMMY_TOKEN_SYMBOL, | ||||
|             constants.DUMMY_TOKEN_DECIMALS, | ||||
|   | ||||
| @@ -33,10 +33,15 @@ describe('EtherToken', () => { | ||||
|         const accounts = await web3Wrapper.getAvailableAddressesAsync(); | ||||
|         account = accounts[0]; | ||||
|  | ||||
|         etherToken = await WETH9Contract.deployFrom0xArtifactAsync(artifacts.WETH9, provider, { | ||||
|             gasPrice, | ||||
|             ...txDefaults, | ||||
|         }); | ||||
|         etherToken = await WETH9Contract.deployFrom0xArtifactAsync( | ||||
|             artifacts.WETH9, | ||||
|             provider, | ||||
|             { | ||||
|                 gasPrice, | ||||
|                 ...txDefaults, | ||||
|             }, | ||||
|             artifacts, | ||||
|         ); | ||||
|     }); | ||||
|     beforeEach(async () => { | ||||
|         await blockchainLifecycle.startAsync(); | ||||
|   | ||||
| @@ -26,7 +26,12 @@ describe('ZRXToken', () => { | ||||
|         const accounts = await web3Wrapper.getAvailableAddressesAsync(); | ||||
|         owner = accounts[0]; | ||||
|         spender = accounts[1]; | ||||
|         zrxToken = await ZRXTokenContract.deployFrom0xArtifactAsync(artifacts.ZRXToken, provider, txDefaults); | ||||
|         zrxToken = await ZRXTokenContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.ZRXToken, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         MAX_UINT = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; | ||||
|     }); | ||||
|     beforeEach(async () => { | ||||
|   | ||||
| @@ -1,4 +1,95 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1565296576, | ||||
|         "version": "2.1.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.1.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies.", | ||||
|                 "pr": 1995 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1564604963 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563957393, | ||||
|         "version": "2.1.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563193019, | ||||
|         "version": "2.1.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563047529, | ||||
|         "version": "2.1.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563006338, | ||||
|         "version": "2.1.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1558712885, | ||||
|         "version": "2.1.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557961111, | ||||
|         "version": "2.1.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.1.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1557799313 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557507213, | ||||
|         "version": "2.1.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.1.1", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,46 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v2.1.12 - _August 8, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.11 - _July 31, 2019_ | ||||
|  | ||||
|     * Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies. (#1995) | ||||
|  | ||||
| ## v2.1.10 - _July 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.9 - _July 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.8 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.7 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.6 - _May 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.5 - _May 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.4 - _May 14, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.2 - _May 10, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.1 - _April 11, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|     "artifactsDir": "./generated-artifacts", | ||||
|     "contractsDir": "./contracts", | ||||
|     "useDockerisedSolc": true, | ||||
|     "useDockerisedSolc": false, | ||||
|     "isOfflineMode": false, | ||||
|     "compilerSettings": { | ||||
|         "evmVersion": "constantinople", | ||||
| @@ -14,6 +14,7 @@ | ||||
|             "*": { | ||||
|                 "*": [ | ||||
|                     "abi", | ||||
|                     "devdoc", | ||||
|                     "evm.bytecode.object", | ||||
|                     "evm.bytecode.sourceMap", | ||||
|                     "evm.deployedBytecode.object", | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc721", | ||||
|     "version": "2.1.1", | ||||
|     "version": "2.1.12", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -47,20 +47,21 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^2.0.9", | ||||
|         "@0x/contracts-gen": "^1.0.8", | ||||
|         "@0x/contracts-test-utils": "^3.1.2", | ||||
|         "@0x/dev-utils": "^2.2.1", | ||||
|         "@0x/sol-compiler": "^3.1.6", | ||||
|         "@0x/abi-gen": "^4.1.0", | ||||
|         "@0x/contracts-gen": "^1.0.13", | ||||
|         "@0x/contracts-test-utils": "^3.1.13", | ||||
|         "@0x/dev-utils": "^2.3.0", | ||||
|         "@0x/sol-compiler": "^3.1.12", | ||||
|         "@0x/tslint-config": "^3.0.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^4.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
|         "solhint": "^1.4.1", | ||||
| @@ -68,13 +69,13 @@ | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^5.0.5", | ||||
|         "@0x/contracts-utils": "^3.1.1", | ||||
|         "@0x/types": "^2.2.2", | ||||
|         "@0x/typescript-typings": "^4.2.2", | ||||
|         "@0x/utils": "^4.3.1", | ||||
|         "@0x/web3-wrapper": "^6.0.5", | ||||
|         "ethereum-types": "^2.1.2", | ||||
|         "@0x/base-contract": "^5.3.1", | ||||
|         "@0x/contracts-utils": "^3.2.1", | ||||
|         "@0x/types": "^2.4.1", | ||||
|         "@0x/typescript-typings": "^4.2.4", | ||||
|         "@0x/utils": "^4.5.0", | ||||
|         "@0x/web3-wrapper": "^6.0.10", | ||||
|         "ethereum-types": "^2.1.4", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -48,6 +48,7 @@ describe('ERC721Token', () => { | ||||
|             artifacts.DummyERC721Token, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|             constants.DUMMY_TOKEN_NAME, | ||||
|             constants.DUMMY_TOKEN_SYMBOL, | ||||
|         ); | ||||
| @@ -55,6 +56,7 @@ describe('ERC721Token', () => { | ||||
|             artifacts.DummyERC721Receiver, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         logDecoder = new LogDecoder(web3Wrapper, artifacts); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
| @@ -176,6 +178,7 @@ describe('ERC721Token', () => { | ||||
|                 artifacts.DummyERC721Token, | ||||
|                 provider, | ||||
|                 txDefaults, | ||||
|                 artifacts, | ||||
|                 constants.DUMMY_TOKEN_NAME, | ||||
|                 constants.DUMMY_TOKEN_SYMBOL, | ||||
|             ); | ||||
| @@ -190,6 +193,7 @@ describe('ERC721Token', () => { | ||||
|                 artifacts.InvalidERC721Receiver, | ||||
|                 provider, | ||||
|                 txDefaults, | ||||
|                 artifacts, | ||||
|             ); | ||||
|             const from = owner; | ||||
|             const to = invalidErc721Receiver.address; | ||||
| @@ -237,6 +241,7 @@ describe('ERC721Token', () => { | ||||
|                 artifacts.DummyERC721Token, | ||||
|                 provider, | ||||
|                 txDefaults, | ||||
|                 artifacts, | ||||
|                 constants.DUMMY_TOKEN_NAME, | ||||
|                 constants.DUMMY_TOKEN_SYMBOL, | ||||
|             ); | ||||
| @@ -251,6 +256,7 @@ describe('ERC721Token', () => { | ||||
|                 artifacts.InvalidERC721Receiver, | ||||
|                 provider, | ||||
|                 txDefaults, | ||||
|                 artifacts, | ||||
|             ); | ||||
|             const from = owner; | ||||
|             const to = invalidErc721Receiver.address; | ||||
|   | ||||
| @@ -1,4 +1,96 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1565296576, | ||||
|         "version": "3.0.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.0.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies.", | ||||
|                 "pr": 1995 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1564607468 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563957393, | ||||
|         "version": "3.0.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563193019, | ||||
|         "version": "3.0.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563047529, | ||||
|         "version": "3.0.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563006338, | ||||
|         "version": "3.0.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1558712885, | ||||
|         "version": "3.0.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557961111, | ||||
|         "version": "3.0.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557799313, | ||||
|         "version": "3.0.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.0.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Update contracts to solidity ^0.5.5 and unpin dependencies", | ||||
|                 "pr": 1796 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1557507213 | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.1.1", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,46 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.0.9 - _August 8, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.8 - _July 31, 2019_ | ||||
|  | ||||
|     * Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies. (#1995) | ||||
|  | ||||
| ## v3.0.7 - _July 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.6 - _July 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.5 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.4 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.3 - _May 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.2 - _May 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.1 - _May 14, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.0 - _May 10, 2019_ | ||||
|  | ||||
|     * Update contracts to solidity ^0.5.5 and unpin dependencies (#1796) | ||||
|  | ||||
| ## v2.1.1 - _April 11, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|     "artifactsDir": "./generated-artifacts", | ||||
|     "contractsDir": "./contracts", | ||||
|     "useDockerisedSolc": true, | ||||
|     "useDockerisedSolc": false, | ||||
|     "isOfflineMode": false, | ||||
|     "compilerSettings": { | ||||
|         "evmVersion": "constantinople", | ||||
| @@ -14,6 +14,7 @@ | ||||
|             "*": { | ||||
|                 "*": [ | ||||
|                     "abi", | ||||
|                     "devdoc", | ||||
|                     "evm.bytecode.object", | ||||
|                     "evm.bytecode.sourceMap", | ||||
|                     "evm.deployedBytecode.object", | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity 0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "./MixinWeth.sol"; | ||||
| @@ -40,6 +40,7 @@ contract Forwarder is | ||||
|         bytes memory _wethAssetData | ||||
|     ) | ||||
|         public | ||||
|         Ownable() | ||||
|         LibConstants( | ||||
|             _exchange, | ||||
|             _zrxAssetData, | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
|  | ||||
| import "@0x/contracts-utils/contracts/src/LibBytes.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/Ownable.sol"; | ||||
| @@ -41,7 +41,7 @@ contract MixinAssets is | ||||
|     /// @param assetData Byte array encoded for the respective asset proxy. | ||||
|     /// @param amount Amount of ERC20 token to withdraw. | ||||
|     function withdrawAsset( | ||||
|         bytes assetData, | ||||
|         bytes calldata assetData, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         external | ||||
| @@ -84,7 +84,7 @@ contract MixinAssets is | ||||
|         // Transfer tokens. | ||||
|         // We do a raw call so we can check the success separate | ||||
|         // from the return data. | ||||
|         bool success = token.call(abi.encodeWithSelector( | ||||
|         (bool success,) = token.call(abi.encodeWithSelector( | ||||
|             ERC20_TRANSFER_SELECTOR, | ||||
|             msg.sender, | ||||
|             amount | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "./libs/LibConstants.sol"; | ||||
| @@ -144,6 +144,7 @@ contract MixinExchangeWrapper is | ||||
|         bytes memory wethAssetData = WETH_ASSET_DATA; | ||||
|  | ||||
|         uint256 ordersLength = orders.length; | ||||
|         uint256 makerAssetFilledAmount = 0; | ||||
|         for (uint256 i = 0; i != ordersLength; i++) { | ||||
|  | ||||
|             // We assume that asset being bought by taker is the same for each order. | ||||
| @@ -175,7 +176,7 @@ contract MixinExchangeWrapper is | ||||
|             addFillResults(totalFillResults, singleFillResults); | ||||
|  | ||||
|             // Stop execution if the entire amount of makerAsset has been bought | ||||
|             uint256 makerAssetFilledAmount = totalFillResults.makerAssetFilledAmount; | ||||
|             makerAssetFilledAmount = totalFillResults.makerAssetFilledAmount; | ||||
|             if (makerAssetFilledAmount >= makerAssetFillAmount) { | ||||
|                 break; | ||||
|             } | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "./libs/LibConstants.sol"; | ||||
| @@ -70,8 +70,8 @@ contract MixinForwarderCore is | ||||
|         bytes[] memory signatures, | ||||
|         LibOrder.Order[] memory feeOrders, | ||||
|         bytes[] memory feeSignatures, | ||||
|         uint256  feePercentage, | ||||
|         address feeRecipient | ||||
|         uint256 feePercentage, | ||||
|         address payable feeRecipient | ||||
|     ) | ||||
|         public | ||||
|         payable | ||||
| @@ -156,8 +156,8 @@ contract MixinForwarderCore is | ||||
|         bytes[] memory signatures, | ||||
|         LibOrder.Order[] memory feeOrders, | ||||
|         bytes[] memory feeSignatures, | ||||
|         uint256  feePercentage, | ||||
|         address feeRecipient | ||||
|         uint256 feePercentage, | ||||
|         address payable feeRecipient | ||||
|     ) | ||||
|         public | ||||
|         payable | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
|  | ||||
| import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol"; | ||||
| import "./libs/LibConstants.sol"; | ||||
| @@ -30,7 +30,7 @@ contract MixinWeth is | ||||
| { | ||||
|     /// @dev Default payabale function, this allows us to withdraw WETH | ||||
|     function () | ||||
|         public | ||||
|         external | ||||
|         payable | ||||
|     { | ||||
|         require( | ||||
| @@ -60,7 +60,7 @@ contract MixinWeth is | ||||
|         uint256 wethSoldExcludingFeeOrders, | ||||
|         uint256 wethSoldForZrx, | ||||
|         uint256 feePercentage, | ||||
|         address feeRecipient | ||||
|         address payable feeRecipient | ||||
|     ) | ||||
|         internal | ||||
|     { | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
|  | ||||
|  | ||||
| contract IAssets { | ||||
| @@ -27,7 +27,7 @@ contract IAssets { | ||||
|     /// @param assetData Byte array encoded for the respective asset proxy. | ||||
|     /// @param amount Amount of ERC20 token to withdraw. | ||||
|     function withdrawAsset( | ||||
|         bytes assetData, | ||||
|         bytes calldata assetData, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         external; | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "./IForwarderCore.sol"; | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol"; | ||||
| @@ -41,8 +41,8 @@ contract IForwarderCore { | ||||
|         bytes[] memory signatures, | ||||
|         LibOrder.Order[] memory feeOrders, | ||||
|         bytes[] memory feeSignatures, | ||||
|         uint256  feePercentage, | ||||
|         address feeRecipient | ||||
|         uint256 feePercentage, | ||||
|         address payable feeRecipient | ||||
|     ) | ||||
|         public | ||||
|         payable | ||||
| @@ -68,8 +68,8 @@ contract IForwarderCore { | ||||
|         bytes[] memory signatures, | ||||
|         LibOrder.Order[] memory feeOrders, | ||||
|         bytes[] memory feeSignatures, | ||||
|         uint256  feePercentage, | ||||
|         address feeRecipient | ||||
|         uint256 feePercentage, | ||||
|         address payable feeRecipient | ||||
|     ) | ||||
|         public | ||||
|         payable | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
|  | ||||
| import "@0x/contracts-utils/contracts/src/LibBytes.sol"; | ||||
| import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol"; | ||||
|   | ||||
| @@ -17,7 +17,7 @@ | ||||
| */ | ||||
|  | ||||
| // solhint-disable | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
|  | ||||
|  | ||||
| /// 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.5.5; | ||||
|  | ||||
| import "../interfaces/IAssets.sol"; | ||||
|  | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol"; | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.4.24; | ||||
| pragma solidity ^0.5.5; | ||||
|  | ||||
|  | ||||
| contract MWeth { | ||||
| @@ -35,7 +35,7 @@ contract MWeth { | ||||
|         uint256 wethSoldExcludingFeeOrders, | ||||
|         uint256 wethSoldForZrx, | ||||
|         uint256 feePercentage, | ||||
|         address feeRecipient | ||||
|         address payable feeRecipient | ||||
|     ) | ||||
|         internal; | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-exchange-forwarder", | ||||
|     "version": "2.1.1", | ||||
|     "version": "3.0.9", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -24,7 +24,6 @@ | ||||
|         "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", | ||||
|         "fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", | ||||
|         "coverage:report:text": "istanbul report text", | ||||
|         "coverage:report:html": "istanbul report html && open coverage/index.html", | ||||
|         "profiler:report:html": "istanbul report html && open coverage/index.html", | ||||
| @@ -47,21 +46,21 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^2.0.9", | ||||
|         "@0x/contract-wrappers": "^9.0.0", | ||||
|         "@0x/contracts-gen": "^1.0.8", | ||||
|         "@0x/contracts-test-utils": "^3.1.2", | ||||
|         "@0x/dev-utils": "^2.2.1", | ||||
|         "@0x/sol-compiler": "^3.1.6", | ||||
|         "@0x/abi-gen": "^4.1.0", | ||||
|         "@0x/contracts-gen": "^1.0.13", | ||||
|         "@0x/contracts-test-utils": "^3.1.13", | ||||
|         "@0x/dev-utils": "^2.3.0", | ||||
|         "@0x/sol-compiler": "^3.1.12", | ||||
|         "@0x/tslint-config": "^3.0.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^4.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
|         "solhint": "^1.4.1", | ||||
| @@ -69,19 +68,19 @@ | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^5.0.5", | ||||
|         "@0x/contracts-asset-proxy": "^2.1.1", | ||||
|         "@0x/contracts-erc20": "1.0.8", | ||||
|         "@0x/contracts-erc721": "1.0.8", | ||||
|         "@0x/contracts-exchange": "1.0.2", | ||||
|         "@0x/contracts-exchange-libs": "1.0.2", | ||||
|         "@0x/contracts-utils": "2.0.1", | ||||
|         "@0x/order-utils": "^7.2.0", | ||||
|         "@0x/types": "^2.2.2", | ||||
|         "@0x/typescript-typings": "^4.2.2", | ||||
|         "@0x/utils": "^4.3.1", | ||||
|         "@0x/web3-wrapper": "^6.0.5", | ||||
|         "ethereum-types": "^2.1.2", | ||||
|         "@0x/base-contract": "^5.3.1", | ||||
|         "@0x/contracts-asset-proxy": "^2.2.5", | ||||
|         "@0x/contracts-erc20": "^2.2.11", | ||||
|         "@0x/contracts-erc721": "^2.1.12", | ||||
|         "@0x/contracts-exchange": "^2.1.11", | ||||
|         "@0x/contracts-exchange-libs": "^3.0.5", | ||||
|         "@0x/contracts-utils": "^3.2.1", | ||||
|         "@0x/order-utils": "^8.2.5", | ||||
|         "@0x/types": "^2.4.1", | ||||
|         "@0x/typescript-typings": "^4.2.4", | ||||
|         "@0x/utils": "^4.5.0", | ||||
|         "@0x/web3-wrapper": "^6.0.10", | ||||
|         "ethereum-types": "^2.1.4", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -32,6 +32,7 @@ const DECIMALS_DEFAULT = 18; | ||||
| const MAX_WETH_FILL_PERCENTAGE = 95; | ||||
|  | ||||
| describe(ContractName.Forwarder, () => { | ||||
|     const dependencyArtifacts = { ...artifacts, ...erc20Artifacts, ...exchangeArtifacts }; | ||||
|     let makerAddress: string; | ||||
|     let owner: string; | ||||
|     let takerAddress: string; | ||||
| @@ -88,8 +89,13 @@ describe(ContractName.Forwarder, () => { | ||||
|         const erc721Balances = await erc721Wrapper.getBalancesAsync(); | ||||
|         erc721MakerAssetIds = erc721Balances[makerAddress][erc721Token.address]; | ||||
|  | ||||
|         wethContract = await WETH9Contract.deployFrom0xArtifactAsync(erc20Artifacts.WETH9, provider, txDefaults); | ||||
|         weth = new DummyERC20TokenContract(wethContract.abi, wethContract.address, provider); | ||||
|         wethContract = await WETH9Contract.deployFrom0xArtifactAsync( | ||||
|             erc20Artifacts.WETH9, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             dependencyArtifacts, | ||||
|         ); | ||||
|         weth = new DummyERC20TokenContract(wethContract.address, provider); | ||||
|         erc20Wrapper.addDummyTokenContract(weth); | ||||
|  | ||||
|         wethAssetData = assetDataUtils.encodeERC20AssetData(wethContract.address); | ||||
| @@ -98,6 +104,7 @@ describe(ContractName.Forwarder, () => { | ||||
|             exchangeArtifacts.Exchange, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             dependencyArtifacts, | ||||
|             zrxAssetData, | ||||
|         ); | ||||
|         exchangeWrapper = new ExchangeWrapper(exchangeInstance, provider); | ||||
| @@ -131,11 +138,12 @@ describe(ContractName.Forwarder, () => { | ||||
|             artifacts.Forwarder, | ||||
|             provider, | ||||
|             txDefaults, | ||||
|             dependencyArtifacts, | ||||
|             exchangeInstance.address, | ||||
|             zrxAssetData, | ||||
|             wethAssetData, | ||||
|         ); | ||||
|         forwarderContract = new ForwarderContract(forwarderInstance.abi, forwarderInstance.address, provider); | ||||
|         forwarderContract = new ForwarderContract(forwarderInstance.address, provider); | ||||
|         forwarderWrapper = new ForwarderWrapper(forwarderContract, provider); | ||||
|         const zrxDepositAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(10000), 18); | ||||
|         await web3Wrapper.awaitTransactionSuccessAsync( | ||||
| @@ -169,6 +177,7 @@ describe(ContractName.Forwarder, () => { | ||||
|                 exchangeArtifacts.Exchange, | ||||
|                 provider, | ||||
|                 txDefaults, | ||||
|                 dependencyArtifacts, | ||||
|                 zrxAssetData, | ||||
|             ); | ||||
|             return expectContractCreationFailedAsync( | ||||
| @@ -176,6 +185,7 @@ describe(ContractName.Forwarder, () => { | ||||
|                     artifacts.Forwarder, | ||||
|                     provider, | ||||
|                     txDefaults, | ||||
|                     dependencyArtifacts, | ||||
|                     exchangeInstance.address, | ||||
|                     zrxAssetData, | ||||
|                     wethAssetData, | ||||
|   | ||||
| @@ -1,4 +1,96 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1565296576, | ||||
|         "version": "3.0.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.0.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies.", | ||||
|                 "pr": 1995 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1564604963 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563957393, | ||||
|         "version": "3.0.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563193019, | ||||
|         "version": "3.0.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1563047529, | ||||
|         "version": "3.0.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.0.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Move `LibTransactionDecoder` to contracts/dev-utils package", | ||||
|                 "pr": 1848 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1563006338 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1558712885, | ||||
|         "version": "2.1.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557961111, | ||||
|         "version": "2.1.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.1.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1557799313 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1557507213, | ||||
|         "version": "2.1.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.1.1", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,46 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.0.5 - _August 8, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.4 - _July 31, 2019_ | ||||
|  | ||||
|     * Updated calls to <contract wrapper>.deployFrom0xArtifactAsync to include artifact dependencies. (#1995) | ||||
|  | ||||
| ## v3.0.3 - _July 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.2 - _July 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.1 - _July 13, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.0.0 - _July 13, 2019_ | ||||
|  | ||||
|     * Move `LibTransactionDecoder` to contracts/dev-utils package (#1848) | ||||
|  | ||||
| ## v2.1.6 - _May 24, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.5 - _May 15, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.4 - _May 14, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.2 - _May 10, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.1 - _April 11, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|     "artifactsDir": "./generated-artifacts", | ||||
|     "contractsDir": "./contracts", | ||||
|     "useDockerisedSolc": true, | ||||
|     "useDockerisedSolc": false, | ||||
|     "isOfflineMode": false, | ||||
|     "compilerSettings": { | ||||
|         "evmVersion": "constantinople", | ||||
| @@ -14,6 +14,7 @@ | ||||
|             "*": { | ||||
|                 "*": [ | ||||
|                     "abi", | ||||
|                     "devdoc", | ||||
|                     "evm.bytecode.object", | ||||
|                     "evm.bytecode.sourceMap", | ||||
|                     "evm.deployedBytecode.object", | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-exchange-libs", | ||||
|     "version": "2.1.1", | ||||
|     "version": "3.0.5", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -47,20 +47,21 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/libs/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^2.0.9", | ||||
|         "@0x/contracts-gen": "^1.0.8", | ||||
|         "@0x/contracts-test-utils": "^3.1.2", | ||||
|         "@0x/dev-utils": "^2.2.1", | ||||
|         "@0x/sol-compiler": "^3.1.6", | ||||
|         "@0x/abi-gen": "^4.1.0", | ||||
|         "@0x/contracts-gen": "^1.0.13", | ||||
|         "@0x/contracts-test-utils": "^3.1.13", | ||||
|         "@0x/dev-utils": "^2.3.0", | ||||
|         "@0x/sol-compiler": "^3.1.12", | ||||
|         "@0x/tslint-config": "^3.0.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^4.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
|         "solhint": "^1.4.1", | ||||
| @@ -68,14 +69,14 @@ | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^5.0.5", | ||||
|         "@0x/contracts-utils": "^3.1.1", | ||||
|         "@0x/order-utils": "^7.2.0", | ||||
|         "@0x/types": "^2.2.2", | ||||
|         "@0x/typescript-typings": "^4.2.2", | ||||
|         "@0x/utils": "^4.3.1", | ||||
|         "@0x/web3-wrapper": "^6.0.5", | ||||
|         "ethereum-types": "^2.1.2", | ||||
|         "@0x/base-contract": "^5.3.1", | ||||
|         "@0x/contracts-utils": "^3.2.1", | ||||
|         "@0x/order-utils": "^8.2.5", | ||||
|         "@0x/types": "^2.4.1", | ||||
|         "@0x/typescript-typings": "^4.2.4", | ||||
|         "@0x/utils": "^4.5.0", | ||||
|         "@0x/web3-wrapper": "^6.0.10", | ||||
|         "ethereum-types": "^2.1.4", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -35,7 +35,7 @@ describe('Exchange libs', () => { | ||||
|     before(async () => { | ||||
|         const accounts = await web3Wrapper.getAvailableAddressesAsync(); | ||||
|         const makerAddress = accounts[0]; | ||||
|         libs = await TestLibsContract.deployFrom0xArtifactAsync(artifacts.TestLibs, provider, txDefaults); | ||||
|         libs = await TestLibsContract.deployFrom0xArtifactAsync(artifacts.TestLibs, provider, txDefaults, artifacts); | ||||
|  | ||||
|         const defaultOrderParams = { | ||||
|             ...constants.STATIC_ORDER_PARAMS, | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user