Compare commits
	
		
			918 Commits
		
	
	
		
			@0x/contra
			...
			protocol@9
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 96e0ad7899 | ||
|  | 5a1fee5d31 | ||
|  | 3557a5e5a9 | ||
|  | 0bd43d5265 | ||
|  | 8fd7c1b386 | ||
|  | 50068750f5 | ||
|  | a7a905de4c | ||
|  | f283108586 | ||
|  | 9afe05095a | ||
|  | 3dab892978 | ||
|  | e40ddb800e | ||
|  | 72a74e7c66 | ||
|  | e8ae64673f | ||
|  | 2451f419c8 | ||
|  | 2394eb62aa | ||
|  | f9078bb1c3 | ||
|  | bf25c81f1c | ||
|  | 03ecc530c3 | ||
|  | d52b1d24d0 | ||
|  | 5083fab06a | ||
|  | 1249bf9ccc | ||
|  | 681f6b3f07 | ||
|  | d3ca1fe96b | ||
|  | 9e4f5815e4 | ||
|  | c3c27eaedc | ||
|  | 4bf6a23d23 | ||
|  | aaaf0d02de | ||
|  | 825cc4d035 | ||
|  | c2d44e5c10 | ||
|  | 0efd0860c8 | ||
|  | a890a06664 | ||
|  | 5befb87071 | ||
|  | 12ba4c373a | ||
|  | 7fd25be02e | ||
|  | aa688c4a92 | ||
|  | fb437551c9 | ||
|  | 6fa1de7889 | ||
|  | 7a42df9a65 | ||
|  | 15a508f3ea | ||
|  | b3c20ff909 | ||
|  | 682c07cb73 | ||
|  | 602605ab4b | ||
|  | 0eff2548d5 | ||
|  | 93ee681204 | ||
|  | d7bea98075 | ||
|  | 437a3b048d | ||
|  | f55a9454b5 | ||
|  | 3b03ad0db4 | ||
|  | 27d679e1f1 | ||
|  | 1e16d59c23 | ||
|  | 1e7c9bbb1f | ||
|  | edda1edc50 | ||
|  | d1eb6279b4 | ||
|  | 4ace79d947 | ||
|  | e5eee96487 | ||
|  | 907adf9145 | ||
|  | c046fe6220 | ||
|  | 84bf20de41 | ||
|  | f5a6f74d9a | ||
|  | 7c7fc51ccf | ||
|  | fa22f6de0d | ||
|  | 4f41214af2 | ||
|  | 607b7169bc | ||
|  | 1253490a38 | ||
|  | 0a37a588e8 | ||
|  | 23ee108089 | ||
|  | 64feeeea75 | ||
|  | 2ebef23b8c | ||
|  | cc9f43ba3b | ||
|  | 5f1c139176 | ||
|  | 9eea7de340 | ||
|  | 4480f84efa | ||
|  | 5a8b8afff1 | ||
|  | 67c95bc0b7 | ||
|  | e70ec02be8 | ||
|  | db81a94adb | ||
|  | 475b608338 | ||
|  | 27e36b112e | ||
|  | f698721484 | ||
|  | 0c08353b2c | ||
|  | a074b49732 | ||
|  | 43b75c7953 | ||
|  | 84a78eafc4 | ||
|  | 3c1ab889dd | ||
|  | 012fff46f6 | ||
|  | 6307ebc3a2 | ||
|  | 88d7e73eba | ||
|  | 9653eb9e70 | ||
|  | ad337271d3 | ||
|  | 7591e99316 | ||
|  | ca20df4752 | ||
|  | 841e4ee666 | ||
|  | e2ee3414ea | ||
|  | 5306cc03e9 | ||
|  | 85f5d32de2 | ||
|  | ab698cec14 | ||
|  | b463a39bfa | ||
|  | 018e25345b | ||
|  | b60fa8a7d7 | ||
|  | 048d8dee60 | ||
|  | 927fe2b58b | ||
|  | 89948b360c | ||
|  | 561b60a24d | ||
|  | 4f82543bdf | ||
|  | 3133c509f9 | ||
|  | 426c15692d | ||
|  | 8c87a77faa | ||
|  | d2018f07a2 | ||
|  | d2e57d8163 | ||
|  | 7403c0255a | ||
|  | 75dcd687e2 | ||
|  | afd4805421 | ||
|  | 6aa582d140 | ||
|  | 534d92fa00 | ||
|  | 37aae134ab | ||
|  | 36bd8f68c9 | ||
|  | c3ad42221e | ||
|  | 602ac1f626 | ||
|  | 3126795efe | ||
|  | dbcb221a59 | ||
|  | 6bbc179f52 | ||
|  | 48e7a391c8 | ||
|  | 2334e64d0c | ||
|  | 14f920ee84 | ||
|  | e10a81023a | ||
|  | f4709ed1cb | ||
|  | e2e14a977a | ||
|  | 866f958a10 | ||
|  | 717db99b38 | ||
|  | 02006118c7 | ||
|  | 9816019bc5 | ||
|  | 9c821dbfc3 | ||
|  | af1b890423 | ||
|  | 673835d2de | ||
|  | 500b57e935 | ||
|  | 3f7d0580c1 | ||
|  | a71c356bba | ||
|  | c3a95b7fb1 | ||
|  | f01540fb35 | ||
|  | 689a8881c2 | ||
|  | 99f5be8378 | ||
|  | 8de0282d92 | ||
|  | f99804d56a | ||
|  | f13d27b749 | ||
|  | 465fd59cbc | ||
|  | 5fdabe6612 | ||
|  | 861871134b | ||
|  | c246d98093 | ||
|  | 02076dba1b | ||
|  | 7b136a5ad8 | ||
|  | 0c4a67fa35 | ||
|  | 668aeb77f7 | ||
|  | 135ae392d5 | ||
|  | 88ba04307c | ||
|  | e4b8000a48 | ||
|  | b9df108314 | ||
|  | 6106185bf6 | ||
|  | 3a3e289864 | ||
|  | 6558632f10 | ||
|  | 376ee6bdff | ||
|  | fc5d759131 | ||
|  | 7c16bb3df8 | ||
|  | 5df74d35d0 | ||
|  | 72fc0c845a | ||
|  | b995715a2c | ||
|  | 857b5c97b0 | ||
|  | 178d9c280a | ||
|  | 2416deba25 | ||
|  | 0ce6243653 | ||
|  | 40dc10729b | ||
|  | 0571244e9e | ||
|  | 3213131cad | ||
|  | 61bf93aac2 | ||
|  | a9d0cec6d1 | ||
|  | b5e3f0b90c | ||
|  | 61f1fe42b0 | ||
|  | 1cfdc49021 | ||
|  | c4d58277cf | ||
|  | 9ac66c2130 | ||
|  | 6366163006 | ||
|  | 85fde8f9a5 | ||
|  | a03d0800b0 | ||
|  | 9cb21006a7 | ||
|  | 649202f1c4 | ||
|  | b798556774 | ||
|  | 03bc15fbdf | ||
|  | b2dfd8740c | ||
|  | 3182c12b4d | ||
|  | f783625d60 | ||
|  | 891aa8e8bf | ||
|  | 4b508d255d | ||
|  | 1cad43bf5d | ||
|  | a0cd727832 | ||
|  | ab90e15015 | ||
|  | 52cbddf054 | ||
|  | db98ff8cb7 | ||
|  | 1d8dd2f89c | ||
|  | 0ae1c926d3 | ||
|  | 1fcab58e2f | ||
|  | a8cbd1a16c | ||
|  | 3aaa0ad6b2 | ||
|  | e34bc77157 | ||
|  | 088b331f19 | ||
|  | 56f2dec441 | ||
|  | ac8b08d3cf | ||
|  | c4ead689a9 | ||
|  | 07ab10b000 | ||
|  | c969a8652a | ||
|  | fb21ca5404 | ||
|  | bbfa9c34ab | ||
|  | 7161bbe836 | ||
|  | ef65aa5bf6 | ||
|  | 2cf31f05a1 | ||
|  | 2b1a1ba0db | ||
|  | 05b25c6229 | ||
|  | 2db52c6983 | ||
|  | 4803e2f68c | ||
|  | 7030572f1d | ||
|  | 6e2eb9c5bb | ||
|  | eb27e260e0 | ||
|  | c72aa653e8 | ||
|  | 4d04b72674 | ||
|  | e3b92d2c8b | ||
|  | 4aa5a89cd7 | ||
|  | c6b9ea5723 | ||
|  | 2dc0bff1ea | ||
|  | 408e66e8b4 | ||
|  | 40fe12a86b | ||
|  | 1adb56f092 | ||
|  | 629d48c766 | ||
|  | c8886febb9 | ||
|  | efe598c8fd | ||
|  | 32218ce25e | ||
|  | f7ae697475 | ||
|  | 6e954385ce | ||
|  | f8df89b506 | ||
|  | a3ff406461 | ||
|  | 221de054f4 | ||
|  | 98e6aa4bac | ||
|  | 199808dc44 | ||
|  | 5d8e35fb68 | ||
|  | 36546480b1 | ||
|  | cd9e408ea3 | ||
|  | 7698f21517 | ||
|  | 10724e5745 | ||
|  | dde76a4dbb | ||
|  | 86ff5c53bb | ||
|  | efef5f122f | ||
|  | 83c942ad8c | ||
|  | 31e90e314c | ||
|  | 33caae705e | ||
|  | 961273a2ff | ||
|  | 46e512a27c | ||
|  | 290a04a0ad | ||
|  | 12ff4ec438 | ||
|  | 1c15ecacb0 | ||
|  | c6d738ed0c | ||
|  | f089f5d87f | ||
|  | 78e3cd39d1 | ||
|  | 1588c1f362 | ||
|  | a35d1b8a9d | ||
|  | 32923ec7e1 | ||
|  | 5a3bd716ad | ||
|  | 84862f15c1 | ||
|  | 9e42dce5c4 | ||
|  | a360109013 | ||
|  | 68d6b3a033 | ||
|  | 733c3046bc | ||
|  | 23d4b6bf1c | ||
|  | 39bd0c5459 | ||
|  | c13ffb2072 | ||
|  | 38bcab1f86 | ||
|  | a24f01c90f | ||
|  | 708e34602b | ||
|  | d60c8ddd5a | ||
|  | eea63292f0 | ||
|  | a97342a594 | ||
|  | 00f55be83e | ||
|  | 90ed283b20 | ||
|  | 61272961a8 | ||
|  | 507690f9db | ||
|  | 90ad5eb6c4 | ||
|  | 7bc9701c81 | ||
|  | a7d502a501 | ||
|  | fbe99b41f8 | ||
|  | 66e2d93e9c | ||
|  | 4672c72fef | ||
|  | ac6b03cd4a | ||
|  | d7de191947 | ||
|  | de7f1fc207 | ||
|  | 99de5a3814 | ||
|  | 4cf566cad8 | ||
|  | 6138955f93 | ||
|  | a57cf68ee4 | ||
|  | 20edcd1ae5 | ||
|  | 5333befd89 | ||
|  | 235e406620 | ||
|  | 5f570b772d | ||
|  | f2507cb94a | ||
|  | f84b375cde | ||
|  | 32d11d1ba5 | ||
|  | 5c9b6eb078 | ||
|  | f53a512e70 | ||
|  | ec08715090 | ||
|  | 79e0a9ef37 | ||
|  | 1ce8a33937 | ||
|  | b3053dfb91 | ||
|  | 3da05f2812 | ||
|  | 0ba79b060d | ||
|  | c4bcc26e29 | ||
|  | 630108ccb6 | ||
|  | 1ab33aa132 | ||
|  | ee456ea6e7 | ||
|  | e7541ac2af | ||
|  | d34d46b7fd | ||
|  | 08ae43aad3 | ||
|  | eb141075c7 | ||
|  | bd3387a408 | ||
|  | e1a48e80e1 | ||
|  | bf899d40a0 | ||
|  | dc66f1b886 | ||
|  | 3753b1a7d0 | ||
|  | 05c5acdb15 | ||
|  | ca63bcc9b0 | ||
|  | 3733d503db | ||
|  | ab28e42c22 | ||
|  | 7e53b4f834 | ||
|  | 3bb60fee19 | ||
|  | 9f7840e12b | ||
|  | f41e13b574 | ||
|  | 4049143630 | ||
|  | 705f46717f | ||
|  | a6cf8ae0b6 | ||
|  | dba6972281 | ||
|  | 52d36f5a8b | ||
|  | 889b58a914 | ||
|  | 43810835d7 | ||
|  | 4b9867f167 | ||
|  | e9c91e59bd | ||
|  | d8844f6970 | ||
|  | 1cdc6e7184 | ||
|  | 36ad373f03 | ||
|  | 78dfb6d525 | ||
|  | 79254de7bc | ||
|  | 1d6aef5cd6 | ||
|  | f9d02c9e27 | ||
|  | 228246089e | ||
|  | b6319ba3d8 | ||
|  | 2636384ead | ||
|  | 0425f76284 | ||
|  | d93e72f56a | ||
|  | 195d543ce3 | ||
|  | 9cda9f69cd | ||
|  | 7b0a1c3630 | ||
|  | a8f3a47240 | ||
|  | db0f3a8780 | ||
|  | 514db24ceb | ||
|  | e738743c89 | ||
|  | f471e1a8a3 | ||
|  | a2f0d5eedf | ||
|  | 2f9b894d71 | ||
|  | bab34c2d21 | ||
|  | a68421b0f8 | ||
|  | e9b0ac8820 | ||
|  | 4f78f55c2a | ||
|  | 156093127b | ||
|  | 47d91bb4e0 | ||
|  | cc31445189 | ||
|  | af78238507 | ||
|  | b30f87f50c | ||
|  | 3cd03ed0f1 | ||
|  | e7ad7c3af7 | ||
|  | 7e8b56eef4 | ||
|  | 458a014e6d | ||
|  | 9b6703398e | ||
|  | 71700e69af | ||
|  | 14d6330b40 | ||
|  | d31d646ecc | ||
|  | 270d7a3f19 | ||
|  | e078f3d479 | ||
|  | 6aa8f17ed5 | ||
|  | 8e73ae3614 | ||
|  | 89117beda2 | ||
|  | e27e6baabe | ||
|  | 15ce90c0ec | ||
|  | 39e157499d | ||
|  | d22c0641fb | ||
|  | 82806b6fcb | ||
|  | fe293d91ee | ||
|  | 7842bb4cad | ||
|  | 6f7e156f49 | ||
|  | 0d19cac487 | ||
|  | f30dfcc572 | ||
|  | 3df39d8cfe | ||
|  | ece93fed78 | ||
|  | 3a2c6ae9d6 | ||
|  | 2ed71b36b6 | ||
|  | ae9c301795 | ||
|  | 68206ffb6e | ||
|  | 25a3c18bfe | ||
|  | d28476e9f7 | ||
|  | 7cd30610f9 | ||
|  | ceb90989d0 | ||
|  | bb39d63d37 | ||
|  | 213709d020 | ||
|  | d0e9081852 | ||
|  | 71cde281b9 | ||
|  | c03f1586e6 | ||
|  | 10aceb164d | ||
|  | 34f516a417 | ||
|  | 5dd686f22f | ||
|  | 5f47ad3363 | ||
|  | e166e9762a | ||
|  | 341c5782e5 | ||
|  | d5180d3ebc | ||
|  | 2c73bbd689 | ||
|  | b10522479c | ||
|  | 2b39ae4800 | ||
|  | 788bdba8cd | ||
|  | 222fd5d822 | ||
|  | eedfc64a8c | ||
|  | 78170b26e9 | ||
|  | f966b6f4df | ||
|  | 053b55fbbf | ||
|  | 84a55a2d84 | ||
|  | 498a50b229 | ||
|  | 766888ec41 | ||
|  | 466d962c07 | ||
|  | ae2a6fb685 | ||
|  | 5afe2616a4 | ||
|  | 72c869649a | ||
|  | 34138fc3b5 | ||
|  | f67d2b96ac | ||
|  | d877d3686c | ||
|  | 8260615b4e | ||
|  | c3f6d48966 | ||
|  | 02f979bc74 | ||
|  | de1c71aacc | ||
|  | ca2aa72e0f | ||
|  | 9a16f5736e | ||
|  | 82774df715 | ||
|  | 314f53c0b3 | ||
|  | 6553ee0130 | ||
|  | d7918ea047 | ||
|  | 4aa9c85503 | ||
|  | f172591059 | ||
|  | dfa7e30e42 | ||
|  | 3fe2013398 | ||
|  | 391d501ce6 | ||
|  | 9edaa3a64e | ||
|  | 6e4e313792 | ||
|  | e6dcf92ec8 | ||
|  | f359de2cac | ||
|  | 2d29014091 | ||
|  | 0450e430f1 | ||
|  | b6700af6a8 | ||
|  | bcee7546ae | ||
|  | 4dac620156 | ||
|  | 74d9df2fb0 | ||
|  | 9d1615fa23 | ||
|  | b1b9949e72 | ||
|  | 957ef5ab77 | ||
|  | 07a681c77e | ||
|  | 145ec8ede1 | ||
|  | 5f5a158060 | ||
|  | 3e99c95791 | ||
|  | 4f83521be8 | ||
|  | aae93bb6a7 | ||
|  | b5eb1c9ee8 | ||
|  | 9d3755db36 | ||
|  | 762e0aec2d | ||
|  | ff9c9241d8 | ||
|  | 5c1ffe7fc8 | ||
|  | b1c3c60def | ||
|  | 8763713596 | ||
|  | 3e823cc9e3 | ||
|  | 1c84709db3 | ||
|  | 9150d6bd2a | ||
|  | 10f29b66b8 | ||
|  | 259aec52a9 | ||
|  | 6554bf9f08 | ||
|  | d8558f5956 | ||
|  | 18bc701e8b | ||
|  | a47795fd3f | ||
|  | a55e8b268c | ||
|  | e8106f04b5 | ||
|  | bdc1dbf08a | ||
|  | 06eeb2088b | ||
|  | 7da9ec2c75 | ||
|  | 297ff10c14 | ||
|  | 1305f4314d | ||
|  | 55474c0599 | ||
|  | 687c79ae81 | ||
|  | 829a353b14 | ||
|  | aced474dc5 | ||
|  | 7c08d5f198 | ||
|  | c546787994 | ||
|  | 31fa530845 | ||
|  | 120714ecfc | ||
|  | 615874d2ec | ||
|  | 67b195c942 | ||
|  | 75689cee96 | ||
|  | 8ba77e95a4 | ||
|  | 7967a8416c | ||
|  | 934fbca860 | ||
|  | e78c8038c7 | ||
|  | f64a42ebb5 | ||
|  | 9164cff234 | ||
|  | 017f98e87e | ||
|  | f33d8670aa | ||
|  | e79db7de89 | ||
|  | 845a42e73a | ||
|  | e58c25aa18 | ||
|  | 8ec44b63b1 | ||
|  | 41907936a1 | ||
|  | 406d2cefc5 | ||
|  | 41cdbc0ec4 | ||
|  | c6ec261c5c | ||
|  | a2db1a3275 | ||
|  | 1e8f2f0e83 | ||
|  | 8491abe142 | ||
|  | d4302538bf | ||
|  | c34e3765ef | ||
|  | 1f86bc06ef | ||
|  | 7e892fac2d | ||
|  | 23789b0692 | ||
|  | 89adbe4127 | ||
|  | 11940fb98e | ||
|  | 13ae335811 | ||
|  | b2dc6ad2fa | ||
|  | 85ca926fd0 | ||
|  | 676698a59b | ||
|  | 22408ecd58 | ||
|  | d36acc7ec7 | ||
|  | a5a68acfec | ||
|  | 7431651666 | ||
|  | 4f91bfd907 | ||
|  | 8d2086870b | ||
|  | 1511ef1a98 | ||
|  | 4e030ce1e8 | ||
|  | 2507ad274b | ||
|  | fb1c149eb9 | ||
|  | d4662f428a | ||
|  | 73c779c13a | ||
|  | b8cc164af1 | ||
|  | 64a391b5f8 | ||
|  | 21a202dd16 | ||
|  | 187dd2fdc3 | ||
|  | c18f3f0b33 | ||
|  | 7162935028 | ||
|  | 9215a73b6c | ||
|  | edd840794c | ||
|  | c30a6eb1aa | ||
|  | 233642af29 | ||
|  | 7dffd0a03e | ||
|  | f7bc3ff49d | ||
|  | 53aabe3cdb | ||
|  | 09b8d7cfc9 | ||
|  | 1512afc7e6 | ||
|  | dde0c76112 | ||
|  | f14b6f2ba2 | ||
|  | 4fced276c4 | ||
|  | 7590471d62 | ||
|  | 0b6bcf6739 | ||
|  | 3a5ce86ed9 | ||
|  | 7b298939e2 | ||
|  | f1f6aa7d80 | ||
|  | 7ce7dd7252 | ||
|  | 01aa556ede | ||
|  | 48ad39c1c7 | ||
|  | 9cab034448 | ||
|  | 0d7a22634c | ||
|  | 3e3bc5c06d | ||
|  | 2a81e468c7 | ||
|  | 0ba67a363e | ||
|  | deae846864 | ||
|  | 3a0d48ad77 | ||
|  | 81d4803b4d | ||
|  | e936c7c507 | ||
|  | ad868af96e | ||
|  | cd14a45414 | ||
|  | f7cd7110ea | ||
|  | 44262bf747 | ||
|  | 0fbbabe208 | ||
|  | b39189fde3 | ||
|  | 18fc1d78f4 | ||
|  | d44a91d10b | ||
|  | 5e9829b2d8 | ||
|  | 2176deae36 | ||
|  | 7c5035aa39 | ||
|  | 5707993995 | ||
|  | f81697527c | ||
|  | 967eff4c58 | ||
|  | d5d07dd34e | ||
|  | b91cc3781d | ||
|  | 87ed0071c4 | ||
|  | 0fed48630c | ||
|  | 7b3e7c98ac | ||
|  | 09f44b0375 | ||
|  | ebfa62637e | ||
|  | cb2cc05cac | ||
|  | f9c9131d81 | ||
|  | 1be9a1cbc7 | ||
|  | b7fda8ecf0 | ||
|  | db16392821 | ||
|  | 7127f541c3 | ||
|  | 32793cc008 | ||
|  | fbaf55cb25 | ||
|  | b8d51fc4e8 | ||
|  | 0c6e05d220 | ||
|  | 4066c17a0f | ||
|  | 429f2bb8dd | ||
|  | 112f4fc4f0 | ||
|  | ecfbd6280f | ||
|  | bf84409839 | ||
|  | a7ce72cae0 | ||
|  | 28402ff7d8 | ||
|  | e1d213d1a3 | ||
|  | c610dd96f5 | ||
|  | 2ba3818b65 | ||
|  | 0e1a5a375a | ||
|  | cfc3daeb65 | ||
|  | 6359f1950e | ||
|  | d2f581853d | ||
|  | 030cb285da | ||
|  | af45409959 | ||
|  | d9a9bc35e3 | ||
|  | c911c3352c | ||
|  | 654abbac25 | ||
|  | 46d5f42c9d | ||
|  | 1509da1215 | ||
|  | 98a99d96aa | ||
|  | d62d81af17 | ||
|  | dba67eb927 | ||
|  | 548c30d6a0 | ||
|  | 1b8b9186a8 | ||
|  | a8cfcfb371 | ||
|  | f7a414bc29 | ||
|  | e05cd1d66b | ||
|  | 511cd90c44 | ||
|  | 8fb2d8da88 | ||
|  | 2fce332ed7 | ||
|  | b23f1eb145 | ||
|  | f694072b5a | ||
|  | 10de266e0f | ||
|  | 71811ed04f | ||
|  | e9638ef95e | ||
|  | 5226bb5596 | ||
|  | b9984b6df4 | ||
|  | 9c11835fee | ||
|  | d9e13d6b99 | ||
|  | dede076835 | ||
|  | c929782e0d | ||
|  | a43c7e36f8 | ||
|  | b95cec9c32 | ||
|  | 9a7d9abe3c | ||
|  | c77b620453 | ||
|  | b348084e2a | ||
|  | ff1811ef90 | ||
|  | 39cf4a7576 | ||
|  | 21b67625a6 | ||
|  | fb0311e675 | ||
|  | 8a14b4afff | ||
|  | e42701599a | ||
|  | 352b1b43f2 | ||
|  | 2922ebd095 | ||
|  | a9e72085dd | ||
|  | ed3d194c90 | ||
|  | 125c53827b | ||
|  | 38781807cd | ||
|  | c046943269 | ||
|  | fe36cd86bb | ||
|  | 401410089c | ||
|  | fa23337519 | ||
|  | ae5421f76e | ||
|  | a2e2b429d5 | ||
|  | ac852b23b3 | ||
|  | e12389a002 | ||
|  | da18e42d2a | ||
|  | 93bdaba8ee | ||
|  | 4cb08a61d5 | ||
|  | 133692ca92 | ||
|  | 4bcc4b3cf8 | ||
|  | 4eb20ca4b6 | ||
|  | 69f7343be5 | ||
|  | 19b28a58d6 | ||
|  | 3c33a93b9c | ||
|  | f2e16dfb21 | ||
|  | 0f689e8051 | ||
|  | 5b44e6ef64 | ||
|  | 49e4ade66f | ||
|  | 3bae27d039 | ||
|  | a77f0c606d | ||
|  | f1de64dcaf | ||
|  | feb672c3cd | ||
|  | a90b463a7d | ||
|  | 5f5f25c978 | ||
|  | 351ea8bc1c | ||
|  | b34edcbf87 | ||
|  | 160519e1fe | ||
|  | 44d626e12e | ||
|  | efb9dc51c9 | ||
|  | deb51434fd | ||
|  | 501070bfb0 | ||
|  | 712958d8c8 | ||
|  | 4d8d944fe5 | ||
|  | 0042e42160 | ||
|  | 85509ea251 | ||
|  | 6063854d06 | ||
|  | 456f8a90b1 | ||
|  | 980246d07a | ||
|  | 141c30b173 | ||
|  | 22f9b03fce | ||
|  | be2db504b9 | ||
|  | cac6f5234f | ||
|  | eb6b32b6ee | ||
|  | 07acc9529e | ||
|  | f7f0152573 | ||
|  | 153533f1d5 | ||
|  | 11622c586a | ||
|  | 7396bb508a | ||
|  | 7df6530f3a | ||
|  | 80787456fa | ||
|  | 4446ac1ca3 | ||
|  | 220039ab00 | ||
|  | 12f2250ab5 | ||
|  | 0c33aa16a1 | ||
|  | 72908b02fe | ||
|  | 223aa04424 | ||
|  | e53248cca6 | ||
|  | c11d661b39 | ||
|  | 4212a08337 | ||
|  | c0553fa9eb | ||
|  | 7f26fafed7 | ||
|  | 3e9309c003 | ||
|  | 1017707475 | ||
|  | e8ff5da209 | ||
|  | 03ed3ac1b0 | ||
|  | 2c97208e74 | ||
|  | a458e81f8d | ||
|  | 83289bc801 | ||
|  | ba2ac6a7b5 | ||
|  | 245b6da577 | ||
|  | 8875f924b0 | ||
|  | ad7868ebe1 | ||
|  | 5effc6ec90 | ||
|  | 4cc9ceabd2 | ||
|  | 464c918134 | ||
|  | 2456adcb68 | ||
|  | 45bc967f30 | ||
|  | d6d4d29257 | ||
|  | 33fdfdc8c0 | ||
|  | 80c8712b2a | ||
|  | 957e3eb93c | ||
|  | 110e1afa8e | ||
|  | 1da8f68871 | ||
|  | 513ddb4cca | ||
|  | 3bdfcb8542 | ||
|  | aee758eca2 | ||
|  | 47ef7fffce | ||
|  | 58d6256607 | ||
|  | b854fcdb72 | ||
|  | 27ca75d94f | ||
|  | bb15f78af0 | ||
|  | ccc9e18132 | ||
|  | d55108ab60 | ||
|  | 84adbcb683 | ||
|  | 0cb5e4553b | ||
|  | 264407b707 | ||
|  | eb5ec58453 | ||
|  | 39c2a757be | ||
|  | 8cdc05f582 | ||
|  | 5f4778c852 | ||
|  | 70add44fc1 | ||
|  | fa617d2e9d | ||
|  | 3c795d365d | ||
|  | 93872ad7a3 | ||
|  | 227676c150 | ||
|  | 5f23833b43 | ||
|  | 121d51b414 | ||
|  | 0e196a59d9 | ||
|  | 63bfd23310 | ||
|  | aadcf8fed0 | ||
|  | 37390e03b4 | ||
|  | 98fc780ade | ||
|  | 1670b21123 | ||
|  | 5602aacbd2 | ||
|  | 6ddbea207f | ||
|  | 261bced822 | ||
|  | a80d1f861c | ||
|  | c541340ef5 | ||
|  | 434af0ae64 | ||
|  | c6379ca1d4 | ||
|  | cdbcada49b | ||
|  | 282930cb9b | ||
|  | b09c751942 | ||
|  | b2047b90b3 | ||
|  | 0c8aec30bd | ||
|  | fafaa3e69b | ||
|  | d19bb3de8d | ||
|  | 481136166c | ||
|  | 4df81a0b9e | ||
|  | da1e9c2d97 | ||
|  | 4b5a02c246 | ||
|  | 0e1572cfd7 | ||
|  | 343caa1ff6 | ||
|  | 403fb3826d | ||
|  | 3cdccb7b4e | ||
|  | d9be78cdb4 | ||
|  | 16dc8255e1 | ||
|  | 2086bfff25 | ||
|  | b9a68c0b8e | ||
|  | 74647f0e88 | ||
|  | 6e29c8bea9 | ||
|  | b36373ab81 | ||
|  | dc437aacf1 | ||
|  | e19dae9b28 | ||
|  | 424cbd4831 | ||
|  | 350feed993 | ||
|  | 7ca4aa0ff4 | ||
|  | bf00e67245 | ||
|  | c5a6e49681 | ||
|  | a509af2875 | ||
|  | 1f789bf396 | ||
|  | 0ccbc7d3d2 | ||
|  | f3c6f26f85 | ||
|  | 338c358df2 | ||
|  | 4bdaa48303 | ||
|  | 36267746da | ||
|  | 7775541eed | ||
|  | 5029be4c83 | ||
|  | 277dbacf68 | ||
|  | 0fdfb03f3c | ||
|  | 17d81bf014 | ||
|  | 568e9be07e | ||
|  | 99b0a95f8a | ||
|  | 0fdd31892a | ||
|  | 7a682604f9 | ||
|  | ce96e35d7d | ||
|  | b7fb5394a7 | ||
|  | aaa62beca7 | ||
|  | 2b58a7242b | ||
|  | 5ed919df79 | ||
|  | baf6372179 | ||
|  | 1a9063a55b | ||
|  | 87999f402f | ||
|  | 109d466260 | ||
|  | 37597eca75 | ||
|  | 5fd767b739 | ||
|  | 0e7a473116 | ||
|  | 05bf55dca8 | ||
|  | cc12ad8d86 | ||
|  | 847a7f470c | ||
|  | 95bebd6d1d | ||
|  | 8179a964ea | ||
|  | d0805d4bbb | ||
|  | f901c401b7 | ||
|  | 6ccadcb928 | ||
|  | 58b6c25d5c | ||
|  | 9cbab26202 | ||
|  | 74bcb468ca | ||
|  | 07a6ba88f4 | ||
|  | 49dff49993 | ||
|  | 68207aac80 | ||
|  | 64652b2ff0 | ||
|  | 659e8991de | ||
|  | 9f495b6dc9 | ||
|  | d8498134ad | ||
|  | 17b2320b0d | ||
|  | 36c457f483 | ||
|  | b8ec7f5e26 | ||
|  | dbc5c0d5d8 | ||
|  | fa886aa849 | ||
|  | 32e1ae2b18 | ||
|  | 61f03b0ea2 | ||
|  | c47825a820 | ||
|  | 2d7cb63c7b | ||
|  | c3d4c13936 | ||
|  | 3f51b9322f | ||
|  | b604e2bd4e | ||
|  | bcd92473d1 | ||
|  | 6f5bf9d146 | ||
|  | 490094939f | ||
|  | d0d7d2772f | ||
|  | 59091896b4 | ||
|  | 3eb1429a25 | ||
|  | bc7504c469 | ||
|  | 99dc4b8e07 | ||
|  | 807904bb86 | ||
|  | 7b8c8348f4 | ||
|  | 9c5ac26170 | ||
|  | 5db065644c | ||
|  | 0cc3a99169 | ||
|  | 2b1545145b | ||
|  | 49b7c9c8a4 | ||
|  | 114119f7c8 | ||
|  | b4ef866c10 | ||
|  | 18ce19a84d | ||
|  | b0fd78d68d | ||
|  | 8186d6277e | ||
|  | 599af2b1a9 | ||
|  | 82de5adbe9 | ||
|  | 82b0f85258 | ||
|  | d97b30dcee | ||
|  | fa8e8ad52d | ||
|  | 7495ac8111 | ||
|  | 08619e2c06 | ||
|  | 5d4bbd5b37 | ||
|  | 9d2aef5006 | ||
|  | bcc3e5ebb0 | ||
|  | e5df51a83a | ||
|  | 7181be8768 | ||
|  | 9608d8fb46 | ||
|  | 8be60e2ff5 | ||
|  | 3c0fd540b1 | ||
|  | 23a7dc9a8a | ||
|  | 77d7afe505 | ||
|  | 90cb86911a | 
| @@ -4,23 +4,13 @@ jobs: | ||||
|     build: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|         environment: | ||||
|             CONTRACTS_COMMIT_HASH: '9ed05f5' | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - checkout | ||||
|             - run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV | ||||
|             # HACK(feuGeneA): commented out this hack as we're changing | ||||
|             # from a circleci-maintained container to a different | ||||
|             # container, and this hack may not apply anymore, as | ||||
|             # suggested by the non-existance of `/home/circleci/.bashrc` | ||||
|             # when running the command below. | ||||
|             # - run: | ||||
|             #       # HACK(albrow): Without this, yarn commands will sometimes | ||||
|             #       # fail with a "permission denied" error. | ||||
|             #       name: Set npm path | ||||
|             #       command: npm set prefix=/home/circleci/npm && echo 'export PATH=$HOME/circleci/npm/bin:$PATH' >> /home/circleci/.bashrc | ||||
|             - run: | ||||
|                   name: install-yarn | ||||
|                   command: npm install --force --global yarn@1.17.0 | ||||
| @@ -38,54 +28,60 @@ jobs: | ||||
|                   path: ~/repo/packages/abi-gen/test-cli/output | ||||
|             - store_artifacts: | ||||
|                   path: ~/repo/packages/contract-wrappers/generated_docs | ||||
|     test-contracts-ganache: | ||||
|     test-exchange-ganache: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - 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-staking | ||||
|     test-exchange-ganache-3.0: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-exchange | ||||
|     test-integrations-ganache-3.0: | ||||
|     test-integrations-ganache: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-integrations | ||||
|     test-contracts-rest-ganache-3.0: | ||||
|     test-contracts-staking-ganache: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - 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-asset-proxy @0x/contracts-exchange-forwarder @0x/contracts-staking @0x/contracts-coordinator @0x/contracts-erc20-bridge-sampler | ||||
|             # TODO(dorothy-zbornak): Re-enable after updating this package for | ||||
|             # 3.0. At that time, also remove exclusion from monorepo | ||||
|             # package.json's test script. | ||||
|             # - run: yarn wsrun test:circleci @0x/contracts-extensions | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-staking | ||||
|     test-contracts-extra-ganache: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: yarn wsrun test:circleci @0x/contracts-exchange-forwarder @0x/contracts-coordinator | ||||
|     test-contracts-rest-ganache: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - 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-asset-proxy @0x/contracts-broker @0x/contracts-zero-ex | ||||
|     test-publish: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|             - image: 0xorg/verdaccio | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
| @@ -95,9 +91,11 @@ jobs: | ||||
|             - run: | ||||
|                   command: yarn test:publish:circleci | ||||
|                   no_output_timeout: 1800 | ||||
|             - store_artifacts: | ||||
|                   path: ~/.npm/_logs | ||||
|     test-doc-generation: | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
| @@ -108,228 +106,35 @@ jobs: | ||||
|                   no_output_timeout: 1200 | ||||
|     test-rest: | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - 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-swapper | ||||
|             - run: yarn wsrun test:circleci @0x/contract-artifacts | ||||
|             - run: yarn wsrun test:circleci @0x/assert | ||||
|             - run: yarn wsrun test:circleci @0x/base-contract | ||||
|             - run: yarn wsrun test:circleci @0x/connect | ||||
|             - run: yarn wsrun test:circleci @0x/contract-wrappers-test | ||||
|             - run: yarn wsrun test:circleci @0x/dev-utils | ||||
|             - run: yarn wsrun test:circleci @0x/json-schemas | ||||
|             - run: yarn wsrun test:circleci @0x/migrations | ||||
|             - run: yarn wsrun test:circleci @0x/order-utils | ||||
|             - run: yarn wsrun test:circleci @0x/orderbook | ||||
|             - run: yarn wsrun test:circleci @0x/sol-compiler | ||||
|             - run: yarn wsrun test:circleci @0x/sol-tracing-utils | ||||
|             - run: yarn wsrun test:circleci @0x/sol-doc | ||||
|             - run: yarn wsrun test:circleci @0x/subproviders | ||||
|             - run: yarn wsrun test:circleci @0x/web3-wrapper | ||||
|             - run: yarn wsrun test:circleci @0x/utils | ||||
|             - run: yarn wsrun test:circleci @0x/instant | ||||
|             - save_cache: | ||||
|                   key: coverage-abi-gen-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/abi-gen/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-assert-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/assert/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-asset-swapper-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/asset-swapper/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/base-contract/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-connect-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/connect/coverage/lcov.info | ||||
|             - run: yarn wsrun test:circleci @0x/asset-swapper | ||||
|             - save_cache: | ||||
|                   key: coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/contract-wrappers-test/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/dev-utils/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-json-schemas-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/json-schemas/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-order-utils-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/order-utils/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/sol-compiler/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-sol-tracing-utils-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/sol-tracing-utils/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-sol-doc-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/sol-doc/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-subproviders-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/subproviders/coverage/lcov.info | ||||
|             - save_cache: | ||||
|                   key: coverage-web3-wrapper-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/packages/web3-wrapper/coverage/lcov.info | ||||
|     test-python: | ||||
|         working_directory: ~/repo | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|             - image: 0xorg/ganache-cli:6.0.0 | ||||
|             - image: 0xorg/mesh:0xV3 | ||||
|               environment: | ||||
|                   ETHEREUM_RPC_URL: 'http://localhost:8545' | ||||
|                   ETHEREUM_CHAIN_ID: '1337' | ||||
|                   VERBOSITY: 5 | ||||
|                   BLOCK_POLLING_INTERVAL: '50ms' | ||||
|                   ETHEREUM_RPC_MAX_REQUESTS_PER_24_HR_UTC: '1778000' | ||||
|               command: | | ||||
|                   sh -c "waitForGanache () { until printf 'POST /\r\nContent-Length: 26\r\n\r\n{\"method\":\"net_listening\"}' | nc localhost 8545 | grep true; do continue; done }; waitForGanache && ./mesh" | ||||
|             - image: 0xorg/launch-kit-backend:v3 | ||||
|               environment: | ||||
|                   RPC_URL: 'http://localhost:8545' | ||||
|                   CHAIN_ID: 1337 | ||||
|                   WHITELIST_ALL_TOKENS: True | ||||
|                   FEE_RECIPIENT: '0x0000000000000000000000000000000000000001' | ||||
|                   MAKER_FEE_UNIT_AMOUNT: 0 | ||||
|                   TAKER_FEE_UNIT_AMOUNT: 0 | ||||
|                   MESH_ENDPOINT: 'ws://localhost:60557' | ||||
|               command: | | ||||
|                   sh -c "waitForMesh () { sleep 30; }; waitForMesh && node_modules/.bin/forever ts/lib/index.js" | ||||
|         steps: | ||||
|             - checkout | ||||
|             - restore_cache: | ||||
|                   key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: | ||||
|                   command: | | ||||
|                       cd python-packages | ||||
|                       python -m ensurepip | ||||
|                       ./pre_install | ||||
|                       ./install | ||||
|             - save_cache: | ||||
|                   key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - '/usr/local/bin' | ||||
|                       - '/usr/local/lib/python3.7/site-packages' | ||||
|             - run: | ||||
|                   command: | | ||||
|                       cd python-packages | ||||
|                       ./parallel coverage run setup.py test | ||||
|                       ./build_docs | ||||
|             - run: | ||||
|                   command: | | ||||
|                       # copy generated wrappers into contract_wrappers/build, | ||||
|                       # JUST so CircleCI will persist them as build artifacts. | ||||
|                       cd python-packages/contract_wrappers/src/zero_ex | ||||
|                       for i in contract_wrappers/[^__]*/; do mkdir -p ../../build/$i; cp $i/__init__.py ../../build/$i; done | ||||
|             - save_cache: | ||||
|                   key: coverage-python-contract-addresses-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/python-packages/contract_addresses/.coverage | ||||
|             - save_cache: | ||||
|                   key: coverage-python-contract-artifacts-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/python-packages/contract_artifacts/.coverage | ||||
|             - save_cache: | ||||
|                   key: coverage-python-contract-demo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/python-packages/contract_demo/.coverage | ||||
|             - save_cache: | ||||
|                   key: coverage-python-json-schemas-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/python-packages/json_schemas/.coverage | ||||
|             - save_cache: | ||||
|                   key: coverage-python-order-utils-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/python-packages/order_utils/.coverage | ||||
|             - save_cache: | ||||
|                   key: coverage-python-sra-client-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - ~/repo/python-packages/sra_client/.coverage | ||||
|             - 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: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|         steps: | ||||
|             - checkout | ||||
|             - restore_cache: | ||||
|                   key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: | ||||
|                   command: | | ||||
|                       cd python-packages/order_utils | ||||
|                       python -m ensurepip | ||||
|                       python -m pip install . | ||||
|             - save_cache: | ||||
|                   key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|                       - '/usr/local/bin' | ||||
|                       - '/usr/local/lib/python3.7/site-packages' | ||||
|                       - '.eggs' | ||||
|                       - '.mypy_cache' | ||||
|                       - '.pytest_cache' | ||||
|                       - '.tox' | ||||
|             - run: | ||||
|                   command: | | ||||
|                       cd python-packages/order_utils | ||||
|                       tox | ||||
|     static-tests-python: | ||||
|         working_directory: ~/repo | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|         steps: | ||||
|             - checkout | ||||
|             - restore_cache: | ||||
|                   key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: | ||||
|                   command: | | ||||
|                       python -m ensurepip | ||||
|                       cd python-packages | ||||
|                       ./pre_install | ||||
|                       ./install | ||||
|                       ./lint | ||||
|     static-tests: | ||||
|         resource_class: large | ||||
|         working_directory: ~/repo | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
| @@ -338,92 +143,43 @@ jobs: | ||||
|             - run: yarn prettier:ci | ||||
|             - run: yarn deps_versions:ci | ||||
|             - run: yarn diff_md_docs:ci | ||||
|             - run: cd packages/0x.js && yarn build:umd:prod | ||||
|             - run: yarn bundlewatch | ||||
|     submit-coverage: | ||||
|         docker: | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs8 | ||||
|             - image: nikolaik/python-nodejs:python3.7-nodejs10 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-abi-gen-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-assert-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-asset-swapper-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-connect-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-json-schemas-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-order-utils-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-sol-tracing-utils-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-sol-doc-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-subproviders-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-web3-wrapper-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-contracts-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-python-json-schemas-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-python-contract-addresses-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-python-contract-artifacts-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-python-contract-demo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-python-sra-client-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
|                       - coverage-python-order-utils-{{ .Environment.CIRCLE_SHA1 }} | ||||
|             - run: yarn report_coverage | ||||
| workflows: | ||||
|     version: 2 | ||||
|     main: | ||||
|         jobs: | ||||
|             - build | ||||
|             - test-exchange-ganache-3.0: | ||||
|                   requires: | ||||
|                       - build | ||||
|             - test-integrations-ganache-3.0: | ||||
|                   requires: | ||||
|                       - build | ||||
|             - test-contracts-rest-ganache-3.0: | ||||
|             # Disabled until we begin actively developing on these packages again. | ||||
|             # - test-exchange-ganache: | ||||
|             #       requires: | ||||
|             #           - build | ||||
|             # - test-integrations-ganache: | ||||
|             #       requires: | ||||
|             #           - build | ||||
|             # - test-contracts-staking-ganache: | ||||
|             #       requires: | ||||
|             #           - build | ||||
|             # - test-contracts-extra-ganache: | ||||
|             #       requires: | ||||
|             #           - build | ||||
|             - test-contracts-rest-ganache: | ||||
|                   requires: | ||||
|                       - build | ||||
|             - test-rest: | ||||
| @@ -438,17 +194,14 @@ workflows: | ||||
|             - test-doc-generation: | ||||
|                   requires: | ||||
|                       - build | ||||
|             - submit-coverage: | ||||
|                   requires: | ||||
|                       - test-contracts-rest-ganache-3.0 | ||||
|                       - test-exchange-ganache-3.0 | ||||
|                       - test-rest | ||||
|                       - static-tests | ||||
|             - test-python: | ||||
|                   requires: | ||||
|                       - build | ||||
|             - static-tests-python: | ||||
|                   requires: | ||||
|                       - build | ||||
|             # skip python tox run for now, as we don't yet have multiple test environments to support. | ||||
|             # - test-rest-python | ||||
|             # Disabled until this repo has a coveralls API key | ||||
|             # - submit-coverage: | ||||
|             #       requires: | ||||
|             #           # Disabled until we begin actively developing on these packages again. | ||||
|             #           # - test-exchange-ganache | ||||
|             #           # - test-integrations-ganache | ||||
|             #           # - test-contracts-staking-ganache | ||||
|             #           # - test-contracts-extra-ganache | ||||
|             #           - test-contracts-rest-ganache | ||||
|             #           - test-rest | ||||
|             #           - static-tests | ||||
|   | ||||
							
								
								
									
										4
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							| @@ -2,7 +2,3 @@ | ||||
|  | ||||
| # Automatically collapse generated files in GitHub. | ||||
| *.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 | ||||
|  | ||||
|   | ||||
							
								
								
									
										26
									
								
								.github/autolabeler.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								.github/autolabeler.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,33 +1,7 @@ | ||||
| python: ['python-packages'] | ||||
| contracts: ['contracts'] | ||||
| @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/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-swapper: ['packages/asset-swapper'] | ||||
| @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'] | ||||
| @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'] | ||||
|   | ||||
							
								
								
									
										48
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| name: publish | ||||
|  | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|       inputs: | ||||
|           ci_status: | ||||
|               description: 'required CI status' | ||||
|               default: 'success' | ||||
|               required: true | ||||
|  | ||||
| jobs: | ||||
|     publish: | ||||
|         runs-on: ubuntu-latest | ||||
|         steps: | ||||
|             - name: 'check successful status' | ||||
|               run: | | ||||
|                   REF_STATUS=$(curl -s \ | ||||
|                   'https://api.github.com/repos/${{ github.repository }}/commits/${{ github.ref }}/status' \ | ||||
|                   | jq .state) | ||||
|                   [[ "${REF_STATUS}" == '"${{ github.event.inputs.ci_status }}"' ]] || \ | ||||
|                   (echo "::error ::${{ github.ref }} does not have a successful CI status" && false) | ||||
|             - uses: actions/checkout@v2 | ||||
|               with: | ||||
|                 ref: 'development' | ||||
|                 fetch-depth: 0 | ||||
|             - uses: actions/setup-node@v1 | ||||
|               with: | ||||
|                 node-version: 10 | ||||
|             - uses: actions/setup-python@v2 | ||||
|             - name: 'configure git' | ||||
|               run: | | ||||
|                   git config --global user.email "github-actions@github.com" | ||||
|                   git config --global user.name "Github Actions" | ||||
|             - name: 'install dependencies' | ||||
|               run: | | ||||
|                   yarn -D | ||||
|             - name: 'build and publish' | ||||
|               run: | | ||||
|                   echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' > .npmrc | ||||
|                   npm run run:publish:gha | ||||
|               env: | ||||
|                   NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} | ||||
|                   GITHUB_TOKEN: ${{ github.token }} | ||||
|             - name: 'merge into main branch' | ||||
|               run: | | ||||
|                   git checkout main && \ | ||||
|                   git merge ${{ github.ref }} && \ | ||||
|                   git push | ||||
							
								
								
									
										24
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -111,8 +111,8 @@ contracts/exchange-forwarder/generated-artifacts/ | ||||
| contracts/exchange-forwarder/test/generated-artifacts/ | ||||
| contracts/dev-utils/generated-artifacts/ | ||||
| contracts/dev-utils/test/generated-artifacts/ | ||||
| packages/sol-tracing-utils/test/fixtures/artifacts/ | ||||
| python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/ | ||||
| contracts/zero-ex/generated-artifacts/ | ||||
| contracts/zero-ex/test/generated-artifacts/ | ||||
|  | ||||
| # generated truffle contract artifacts/ | ||||
| contracts/broker/build/ | ||||
| @@ -165,24 +165,8 @@ contracts/exchange-forwarder/generated-wrappers/ | ||||
| contracts/exchange-forwarder/test/generated-wrappers/ | ||||
| contracts/dev-utils/generated-wrappers/ | ||||
| contracts/dev-utils/test/generated-wrappers/ | ||||
| python-packages/contract_wrappers/src/zero_ex/contract_wrappers/*/__init__.py | ||||
|  | ||||
| # solc-bin in sol-compiler | ||||
| packages/sol-compiler/solc_bin/ | ||||
|  | ||||
| # python stuff | ||||
| .eggs | ||||
| .mypy_cache | ||||
| .tox | ||||
| python-packages/*/build | ||||
| python-packages/*/dist | ||||
| __pycache__ | ||||
| python-packages/*/src/*.egg-info | ||||
| python-packages/*/.coverage | ||||
|  | ||||
| # python keeps package-local copies of json schemas and contract addresses | ||||
| python-packages/json_schemas/src/zero_ex/json_schemas/schemas | ||||
| python-packages/contract_addresses/src/zero_ex/contract_addresses/addresses.json | ||||
| contracts/zero-ex/generated-wrappers/ | ||||
| contracts/zero-ex/test/generated-wrappers/ | ||||
|  | ||||
| # Doc README copy | ||||
| packages/*/docs/README.md | ||||
|   | ||||
| @@ -40,10 +40,6 @@ lib | ||||
| /contracts/erc20/test/generated-wrappers | ||||
| /contracts/erc20/generated-artifacts | ||||
| /contracts/erc20/test/generated-artifacts | ||||
| /contracts/erc20-bridge-sampler/generated-wrappers | ||||
| /contracts/erc20-bridge-sampler/test/generated-wrappers | ||||
| /contracts/erc20-bridge-sampler/generated-artifacts | ||||
| /contracts/erc20-bridge-sampler/test/generated-artifacts | ||||
| /contracts/erc721/generated-wrappers | ||||
| /contracts/erc721/test/generated-wrappers | ||||
| /contracts/erc721/generated-artifacts | ||||
| @@ -64,6 +60,10 @@ lib | ||||
| /contracts/dev-utils/test/generated-wrappers | ||||
| /contracts/dev-utils/generated-artifacts | ||||
| /contracts/dev-utils/test/generated-artifacts | ||||
| /contracts/zero-ex/generated-wrappers | ||||
| /contracts/zero-ex/test/generated-wrappers | ||||
| /contracts/zero-ex/generated-artifacts | ||||
| /contracts/zero-ex/test/generated-artifacts | ||||
| /contracts/staking/build/ | ||||
| /contracts/coordinator/build/ | ||||
| /contracts/exchange/build/ | ||||
| @@ -76,19 +76,11 @@ lib | ||||
| /contracts/erc1155/build/ | ||||
| /contracts/extensions/build/ | ||||
| /contracts/exchange-forwarder/build/ | ||||
| /contracts/dev-utils/build/ | ||||
| /packages/abi-gen/test-cli/output | ||||
| /packages/json-schemas/schemas | ||||
| /python-packages/json_schemas/src/zero_ex/json_schemas/schemas | ||||
| /packages/sra-spec/public/ | ||||
| /packages/asset-swapper/generated-artifacts | ||||
| /packages/asset-swapper/generated-wrappers | ||||
| /packages/asset-swapper/test/generated-artifacts | ||||
| /packages/asset-swapper/test/generated-wrappers | ||||
| package.json | ||||
| scripts/postpublish_utils.js | ||||
| 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 | ||||
| packages/*/docs | ||||
| docs/ | ||||
| *.sol | ||||
|   | ||||
| @@ -2,5 +2,6 @@ | ||||
|     "printWidth": 120, | ||||
|     "tabWidth": 4, | ||||
|     "singleQuote": true, | ||||
|     "trailingComma": "all" | ||||
|     "trailingComma": "all", | ||||
|     "bracketSpacing": true | ||||
| } | ||||
|   | ||||
							
								
								
									
										23
									
								
								.readthedocs.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								.readthedocs.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| # Read the Docs configuration file | ||||
| # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details | ||||
|  | ||||
| # Required | ||||
| version: 2 | ||||
|  | ||||
| # Build documentation in the docs/ directory with Sphinx | ||||
| sphinx: | ||||
|   configuration: docs/conf.py | ||||
|  | ||||
| # Build documentation with MkDocs | ||||
| #mkdocs: | ||||
| #  configuration: mkdocs.yml | ||||
|  | ||||
| # Optionally build your docs in additional formats such as PDF | ||||
| #formats: | ||||
| #  - pdf | ||||
|  | ||||
| # Optionally set the version of Python and requirements required to build your docs | ||||
| python: | ||||
|   version: 3.7 | ||||
|   install: | ||||
|     - requirements: docs/requirements.txt | ||||
							
								
								
									
										26
									
								
								CODEOWNERS
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								CODEOWNERS
									
									
									
									
									
								
							| @@ -9,30 +9,10 @@ packages/asset-swapper/  @BMillman19 @fragosti @dave4506 | ||||
| packages/instant/  @BMillman19 @fragosti @dave4506 | ||||
|  | ||||
| # Dev tools & setup | ||||
| .circleci/ @LogvinovLeon | ||||
| packages/abi-gen/ @feuGeneA | ||||
| packages/base-contract/ @xianny | ||||
| packages/connect/ @fragosti  | ||||
| packages/abi-gen-templates/ @feuGeneA @xianny | ||||
| .circleci/ @dorothy-zbornak | ||||
| packages/contract-addresses/ @abandeali1 | ||||
| packages/contract-artifacts/ @abandeali1 | ||||
| packages/dev-utils/ @LogvinovLeon @fabioberger | ||||
| packages/devnet/ @albrow | ||||
| packages/ethereum-types/ @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 | ||||
| packages/sol-trace/ @LogvinovLeon | ||||
| packages/sol-tracing-utils/ @LogvinovLeon | ||||
| packages/sol-resolver/ @LogvinovLeon | ||||
| packages/subproviders/ @fabioberger @dekz | ||||
| packages/verdaccio/ @albrow | ||||
| packages/web3-wrapper/ @LogvinovLeon @fabioberger | ||||
| python-packages/ @feuGeneA | ||||
| packages/utils/ @hysz | ||||
| packages/order-utils/ @dorothy-zbornak  | ||||
|  | ||||
| # Protocol/smart contracts | ||||
| contracts/ @abandeali1 @hysz | ||||
| contracts/ @abandeali1 @hysz @dorothy-zbornak @mzhu25 | ||||
|   | ||||
| @@ -4,9 +4,9 @@ We welcome contributions from anyone on the internet and are grateful for even t | ||||
|  | ||||
| ### Getting started | ||||
|  | ||||
| 1.  Fork `0xproject/0x-monorepo` | ||||
| 1.  Fork `0xproject/0x-tools` | ||||
| 2.  Clone your fork | ||||
| 3.  Follow the [installation & build steps](https://github.com/0xProject/0x-monorepo#install-dependencies) in the repo's top-level README. | ||||
| 3.  Follow the [installation & build steps](https://github.com/0xProject/0x-tools#install-dependencies) in the repo's top-level README. | ||||
| 4.  Setup the recommended [Development Tooling](#development-tooling). | ||||
| 5.  Open a PR with the `[WIP]` flag against the `development` branch and describe the change you are intending to undertake in the PR description. (see [our branch naming conventions](#branch-structure)) | ||||
|  | ||||
| @@ -59,11 +59,11 @@ We strongly recommend you use the [VSCode](https://code.visualstudio.com/) text | ||||
|  | ||||
| #### Linter | ||||
|  | ||||
| We use [TSLint](https://palantir.github.io/tslint/) with [custom configs](https://github.com/0xProject/0x-monorepo/tree/development/packages/tslint-config) to keep our code-style consistent. | ||||
| We use [TSLint](https://palantir.github.io/tslint/) with [custom configs](https://github.com/0xProject/0x-tools/tree/development/packages/tslint-config) to keep our code-style consistent. | ||||
|  | ||||
| Use `yarn:lint` to lint the entire monorepo, and `PKG={PACKAGE_NAME} yarn lint` to lint a specific package. | ||||
|  | ||||
| If you want to change a rule, or add a custom rule, please make these changes to our [tslint-config](https://github.com/0xProject/0x-monorepo/tree/development/packages/tslint-config) package. All other packages have it as a dependency. | ||||
| If you want to change a rule, or add a custom rule, please make these changes to our [tslint-config](https://github.com/0xProject/0x-tools/tree/development/packages/tslint-config) package. All other packages have it as a dependency. | ||||
|  | ||||
| Integrate it into your text editor: | ||||
|  | ||||
| @@ -94,12 +94,12 @@ A few of our coding conventions are not yet enforced by the linter/auto-formatte | ||||
|  | ||||
| ### Fix `submit-coverage` CI failure | ||||
|  | ||||
| If you simply fork the repo and then create a PR from it, your PR will fail the `submit-coverage` check on CI. This is because the 0x CircleCI configuration sets the `COVERALLS_REPO_TOKEN` environment variable to the token for `0xProject/0x-monorepo`, but when running the check against your fork the token needs to match your repo's name `your-username/0x-monorepo`. | ||||
| If you simply fork the repo and then create a PR from it, your PR will fail the `submit-coverage` check on CI. This is because the 0x CircleCI configuration sets the `COVERALLS_REPO_TOKEN` environment variable to the token for `0xProject/0x-tools`, but when running the check against your fork the token needs to match your repo's name `your-username/0x-tools`. | ||||
|  | ||||
| To facilitate this check, after creating your fork, but before creating the branch for your PR, do the following: | ||||
|  | ||||
| 1.  Log in to [coveralls.io](https://coveralls.io/), go to `Add Repos`, and enable your fork. Then go to the settings for that repo, and copy the `Repo Token` identifier. | ||||
| 2.  Log in to [CircleCI](https://circleci.com/login), go to `Add Projects`, click the `Set Up Project` button corresponding to your fork, and then click `Start Building`. (Aside from step 3 below, no actual set up is needed, since it will use the `.circleci/config.yml` file in 0x-monorepo, so you can ignore all of the instruction/explanation given on the page with the `Start Building` button.) | ||||
| 2.  Log in to [CircleCI](https://circleci.com/login), go to `Add Projects`, click the `Set Up Project` button corresponding to your fork, and then click `Start Building`. (Aside from step 3 below, no actual set up is needed, since it will use the `.circleci/config.yml` file in 0x-tools, so you can ignore all of the instruction/explanation given on the page with the `Start Building` button.) | ||||
| 3.  In CircleCI, configure your project to add an environment variable, with name `COVERALLS_REPO_TOKEN`, and for the value paste in the `Repo Token` you copied in step 1. | ||||
|  | ||||
| Now, when you push to your branch, CircleCI will automatically run all of the checks in your own instance, and the coverage check will work since it has the proper `Repo Token`, and the PR will magically refer to your own checks rather than running them in the 0x CircleCI instance. | ||||
|   | ||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| Copyright 2017 ZeroEx Intl. | ||||
| Copyright 2020 ZeroEx Labs | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
|   | ||||
							
								
								
									
										76
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								README.md
									
									
									
									
									
								
							| @@ -8,7 +8,7 @@ This repository is a monorepo including the 0x protocol smart contracts and nume | ||||
|  | ||||
| [website-url]: https://0x.org | ||||
|  | ||||
| [](https://circleci.com/gh/0xProject/0x-monorepo) | ||||
| [](https://circleci.com/gh/0xProject/protocool) | ||||
| [](https://coveralls.io/github/0xProject/0x-monorepo?branch=development) | ||||
| [](https://discordapp.com/invite/d3FTX3M) | ||||
| [](https://opensource.org/licenses/Apache-2.0) | ||||
| @@ -17,17 +17,6 @@ This repository is a monorepo including the 0x protocol smart contracts and nume | ||||
|  | ||||
| Visit our [developer portal](https://0x.org/docs/tools/order-utils) for a comprehensive list of core & community maintained packages. All packages maintained with this monorepo are listed below. | ||||
|  | ||||
| ### Python Packages | ||||
|  | ||||
| | Package                                                        | Version                                                                                                             | Description                                                                                       | | ||||
| | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | ||||
| | [`0x-contract-addresses`](/python-packages/contract_addresses) | [](https://pypi.org/project/0x-contract-addresses/) | A tiny utility library for getting known deployed contract addresses for a particular network     | | ||||
| | [`0x-contract-artifacts`](/python-packages/contract_artifacts) | [](https://pypi.org/project/0x-contract-artifacts/) | 0x smart contract compilation artifacts                                                           | | ||||
| | [`0x-contract-wrappers`](/python-packages/contract_wrappers)   | [](https://pypi.org/project/0x-contract-wrappers/)   | 0x smart contract wrappers                                                                        | | ||||
| | [`0x-json-schemas`](/python-packages/json_schemas)             | [](https://pypi.org/project/0x-json-schemas/)             | 0x-related JSON schemas                                                                           | | ||||
| | [`0x-order-utils`](/python-packages/order_utils)               | [](https://pypi.org/project/0x-order-utils/)               | A set of utilities for generating, parsing, signing and validating 0x orders                      | | ||||
| | [`0x-sra-client`](/python-packages/sra_client)                 | [](https://pypi.org/project/0x-sra-client/)                 | A Python client for interacting with servers conforming to the Standard Relayer API specification | | ||||
|  | ||||
| ### Solidity Packages | ||||
|  | ||||
| These packages are all under development. See [/contracts/README.md](/contracts/README.md) for a list of deployed packages. | ||||
| @@ -53,50 +42,13 @@ These packages are all under development. See [/contracts/README.md](/contracts/ | ||||
|  | ||||
| #### 0x-specific packages | ||||
|  | ||||
| | Package                                                  | Version                                                                                                                 | Description                                                                                       | | ||||
| | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | ||||
| | [`0x.js`](/packages/0x.js)                               | [](https://www.npmjs.com/package/0x.js)                                   | An aggregate package combining many smaller utility packages for interacting with the 0x protocol | | ||||
| | [`@0x/contract-addresses`](/packages/contract-addresses) | [](https://www.npmjs.com/package/@0x/contract-addresses) | A tiny utility library for getting known deployed contract addresses for a particular network.    | | ||||
| | [`@0x/contract-wrappers`](/packages/contract-wrappers)   | [](https://www.npmjs.com/package/@0x/contract-wrappers)   | JS/TS wrappers for interacting with the 0x smart contracts                                        | | ||||
| | [`@0x/order-utils`](/packages/order-utils)               | [](https://www.npmjs.com/package/@0x/order-utils)               | A set of utilities for generating, parsing, signing and validating 0x orders                      | | ||||
| | [`@0x/json-schemas`](/packages/json-schemas)             | [](https://www.npmjs.com/package/@0x/json-schemas)             | 0x-related JSON schemas                                                                           |  | | ||||
| | [`@0x/migrations`](/packages/migrations)                 | [](https://www.npmjs.com/package/@0x/migrations)                 | Migration tool for deploying 0x smart contracts on private testnets                               | | ||||
| | [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts                                                           |  | | ||||
| | [`@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-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 | ||||
|  | ||||
| | Package                                      | Version                                                                                                     | Description                                                                                                                                                                             | | ||||
| | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||||
| | [`@0x/web3-wrapper`](/packages/web3-wrapper) | [](https://www.npmjs.com/package/@0x/web3-wrapper) | An Ethereum JSON RPC client                                                                                                                                                             | | ||||
| | [`@0x/sol-compiler`](/packages/sol-compiler) | [](https://www.npmjs.com/package/@0x/sol-compiler) | A wrapper around solc-js that adds smart re-compilation, ability to compile an entire project, Solidity version specific compilation, standard input description support and much more. | | ||||
| | [`@0x/sol-coverage`](/packages/sol-coverage) | [](https://www.npmjs.com/package/@0x/sol-coverage) | A solidity test coverage tool                                                                                                                                                           | | ||||
| | [`@0x/sol-profiler`](/packages/sol-profiler) | [](https://www.npmjs.com/package/@0x/sol-profiler) | A solidity gas cost profiler                                                                                                                                                            | | ||||
| | [`@0x/sol-trace`](/packages/sol-trace)       | [](https://www.npmjs.com/package/@0x/sol-trace)       | A solidity stack trace tool                                                                                                                                                             | | ||||
| | [`@0x/sol-resolver`](/packages/sol-resolver) | [](https://www.npmjs.com/package/@0x/sol-resolver) | Import resolver for smart contracts dependencies                                                                                                                                        | | ||||
| | [`@0x/subproviders`](/packages/subproviders) | [](https://www.npmjs.com/package/@0x/subproviders) | Web3 provider middlewares (e.g. LedgerSubprovider)                                                                                                                                      | | ||||
| | [`@0x/sol-doc`](/packages/sol-doc)           | [](https://www.npmjs.com/package/@0x/sol-doc)           | Solidity documentation generator                                                                                                                                                        | | ||||
|  | ||||
| #### 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/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                       | | ||||
|  | ||||
| #### Private Packages | ||||
|  | ||||
| | Package                            | Description                                                                      | | ||||
| | ---------------------------------- | -------------------------------------------------------------------------------- | | ||||
| | [`@0x/instant`](/packages/instant) | A free and flexible way to offer simple crypto purchasing in any app or website. | | ||||
| | Package                                                  | Version                                                                                                                 | Description                                                                                    | | ||||
| | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | ||||
| | [`@0x/contract-addresses`](/packages/contract-addresses) | [](https://www.npmjs.com/package/@0x/contract-addresses) | A tiny utility library for getting known deployed contract addresses for a particular network. | | ||||
| | [`@0x/contract-wrappers`](/packages/contract-wrappers)   | [](https://www.npmjs.com/package/@0x/contract-wrappers)   | JS/TS wrappers for interacting with the 0x smart contracts                                     | | ||||
| | [`@0x/order-utils`](/packages/order-utils)               | [](https://www.npmjs.com/package/@0x/order-utils)               | A set of utilities for generating, parsing, signing and validating 0x orders                   | | ||||
| | [`@0x/migrations`](/packages/migrations)                 | [](https://www.npmjs.com/package/@0x/migrations)                 | Migration tool for deploying 0x smart contracts on private testnets                            | | ||||
| | [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts                                                        |  | | ||||
|  | ||||
| ## Usage | ||||
|  | ||||
| @@ -129,8 +81,6 @@ Then install dependencies | ||||
| yarn install | ||||
| ``` | ||||
|  | ||||
| You will also need to have Python 3 installed, in order to build and run the tests of `abi-gen`'s command-line interface, which is integrated with the yarn build, yarn test, and yarn lint commands described below. More specifically, your local pip should resolve to the Python 3 version of pip, not a Python 2.x version. | ||||
|  | ||||
| ### Build | ||||
|  | ||||
| To build all packages: | ||||
| @@ -142,7 +92,7 @@ yarn build | ||||
| To build a specific package: | ||||
|  | ||||
| ```bash | ||||
| PKG=@0x/web3-wrapper yarn build | ||||
| PKG=@0x/contract-wrappers yarn build | ||||
| ``` | ||||
|  | ||||
| To build all contracts packages: | ||||
| @@ -165,7 +115,7 @@ To watch a specific package and all it's dependent packages: | ||||
| PKG=[NPM_PACKAGE_NAME] yarn watch | ||||
|  | ||||
| e.g | ||||
| PKG=@0x/web3-wrapper yarn watch | ||||
| PKG=@0x/contract-wrappers yarn watch | ||||
| ``` | ||||
|  | ||||
| ### Clean | ||||
| @@ -193,7 +143,7 @@ yarn rebuild | ||||
| To re-build (clean & build) a specific package & it's deps: | ||||
|  | ||||
| ```bash | ||||
| PKG=0x.js yarn rebuild | ||||
| PKG=@0x/contract-wrappers yarn rebuild | ||||
| ``` | ||||
|  | ||||
| ### Lint | ||||
| @@ -207,7 +157,7 @@ yarn lint | ||||
| Lint a specific package: | ||||
|  | ||||
| ```bash | ||||
| PKG=0x.js yarn lint | ||||
| PKG=@0x/contract-wrappers yarn lint | ||||
| ``` | ||||
|  | ||||
| ### Run Tests | ||||
| @@ -221,7 +171,7 @@ yarn test | ||||
| Run a specific package's test: | ||||
|  | ||||
| ```bash | ||||
| PKG=@0x/web3-wrapper yarn test | ||||
| PKG=@0x/contract-wrappers yarn test | ||||
| ``` | ||||
|  | ||||
| Run all contracts packages tests: | ||||
|   | ||||
| @@ -13,9 +13,11 @@ | ||||
|         "indent": ["error", 4], | ||||
|         "max-line-length": ["warn", 160], | ||||
|         "no-inline-assembly": false, | ||||
|         "no-empty-blocks": false, | ||||
|         "quotes": ["error", "double"], | ||||
|         "separate-by-one-line-in-contract": "error", | ||||
|         "space-after-comma": "error", | ||||
|         "statement-indent": "error" | ||||
|         "statement-indent": "error", | ||||
|         "no-empty-blocks": false | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,240 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1611648096, | ||||
|         "version": "3.7.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1610510890, | ||||
|         "version": "3.7.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1609802516, | ||||
|         "version": "3.7.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608692071, | ||||
|         "version": "3.7.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608245516, | ||||
|         "version": "3.7.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.7.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Fix Bancor support of ETH", | ||||
|                 "pr": 88 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1608105788 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607485227, | ||||
|         "version": "3.6.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607381756, | ||||
|         "version": "3.6.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1606961263, | ||||
|         "version": "3.6.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605763885, | ||||
|         "version": "3.6.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605302002, | ||||
|         "version": "3.6.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604385937, | ||||
|         "version": "3.6.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604376968, | ||||
|         "version": "3.6.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604355662, | ||||
|         "version": "3.6.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603851023, | ||||
|         "version": "3.6.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.6.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add `SwerveBridge` and `SnowSwapBridge` (duplicate of `CurveBridge`)", | ||||
|                 "pr": 2707 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1603833198 | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.5.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Update `CurveBridge` to support more varied curves", | ||||
|                 "pr": 2633 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Export DexForwarderBridgeContract", | ||||
|                 "pr": 2656 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add BancorBridge and IBancorNetwork, ", | ||||
|                 "pr": 2650 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Added `MStableBridge`", | ||||
|                 "pr": 2662 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Added `MooniswapBridge`", | ||||
|                 "pr": 2675 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Reworked `KyberBridge`", | ||||
|                 "pr": 2683 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Added `CreamBridge`", | ||||
|                 "pr": 2715 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Added `ShellBridge`", | ||||
|                 "pr": 2722 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Added `DODOBridge`", | ||||
|                 "pr": 2701 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1603265572 | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.4.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Fix instability with DFB.", | ||||
|                 "pr": 2616 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add `BalancerBridge`", | ||||
|                 "pr": 2613 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1594788383 | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.3.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Use `LibERC20Token.approveIfBelow()` in DEX bridges for for approvals.", | ||||
|                 "pr": 2512 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Emit `ERC20BridgeTransfer` events in bridges.", | ||||
|                 "pr": 2512 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Change names of `ERC20BridgeTransfer` args to be less ambiguous.", | ||||
|                 "pr": 2524 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Added `MixinGasToken` allowing Gas Tokens to be freed", | ||||
|                 "pr": 2523 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add `DexForwaderBridge` bridge contract.", | ||||
|                 "pr": 2525 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add `UniswapV2Bridge` bridge contract.", | ||||
|                 "pr": 2590 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add Gas Token freeing to `DexForwarderBridge` contract.", | ||||
|                 "pr": 2536 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1592969527 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1583220306, | ||||
|         "version": "3.2.5", | ||||
| @@ -69,7 +305,7 @@ | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add `setOperators()` to `IDydx`", | ||||
|                 "pr": "TODO" | ||||
|                 "pr": 2462 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1581204851 | ||||
|   | ||||
| @@ -5,6 +5,97 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.7.5 - _January 26, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.7.4 - _January 13, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.7.3 - _January 4, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.7.2 - _December 23, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.7.1 - _December 17, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.7.0 - _December 16, 2020_ | ||||
|  | ||||
|     * Fix Bancor support of ETH (#88) | ||||
|  | ||||
| ## v3.6.9 - _December 9, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.6.8 - _December 7, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.6.7 - _December 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.6.6 - _November 19, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.6.5 - _November 13, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.6.4 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.6.3 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.6.2 - _November 2, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.6.1 - _October 28, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.6.0 - _October 27, 2020_ | ||||
|  | ||||
|     * Add `SwerveBridge` and `SnowSwapBridge` (duplicate of `CurveBridge`) (#2707) | ||||
|  | ||||
| ## v3.5.0 - _October 21, 2020_ | ||||
|  | ||||
|     * Update `CurveBridge` to support more varied curves (#2633) | ||||
|     * Export DexForwarderBridgeContract (#2656) | ||||
|     * Add BancorBridge and IBancorNetwork,  (#2650) | ||||
|     * Added `MStableBridge` (#2662) | ||||
|     * Added `MooniswapBridge` (#2675) | ||||
|     * Reworked `KyberBridge` (#2683) | ||||
|     * Added `CreamBridge` (#2715) | ||||
|     * Added `ShellBridge` (#2722) | ||||
|     * Added `DODOBridge` (#2701) | ||||
|  | ||||
| ## v3.4.0 - _July 15, 2020_ | ||||
|  | ||||
|     * Fix instability with DFB. (#2616) | ||||
|     * Add `BalancerBridge` (#2613) | ||||
|  | ||||
| ## v3.3.0 - _June 24, 2020_ | ||||
|  | ||||
|     * Use `LibERC20Token.approveIfBelow()` in DEX bridges for for approvals. (#2512) | ||||
|     * Emit `ERC20BridgeTransfer` events in bridges. (#2512) | ||||
|     * Change names of `ERC20BridgeTransfer` args to be less ambiguous. (#2524) | ||||
|     * Added `MixinGasToken` allowing Gas Tokens to be freed (#2523) | ||||
|     * Add `DexForwaderBridge` bridge contract. (#2525) | ||||
|     * Add `UniswapV2Bridge` bridge contract. (#2590) | ||||
|     * Add Gas Token freeing to `DexForwarderBridge` contract. (#2536) | ||||
|  | ||||
| ## v3.2.5 - _March 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
| @@ -32,7 +123,7 @@ CHANGELOG | ||||
|     * Fix broken tests. (#2462) | ||||
|     * Remove dependency on `@0x/contracts-dev-utils` (#2462) | ||||
|     * Add asset data decoding functions (#2462) | ||||
|     * Add `setOperators()` to `IDydx` (#TODO) | ||||
|     * Add `setOperators()` to `IDydx` (#2462) | ||||
|  | ||||
| ## v3.1.3 - _February 6, 2020_ | ||||
|  | ||||
|   | ||||
							
								
								
									
										103
									
								
								contracts/asset-proxy/contracts/src/bridges/BalancerBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								contracts/asset-proxy/contracts/src/bridges/BalancerBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
|  | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
| import "../interfaces/IBalancerPool.sol"; | ||||
|  | ||||
|  | ||||
| contract BalancerBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` | ||||
|     ///      token encoded in the bridge data, then transfers the bought | ||||
|     ///      tokens to `to`. | ||||
|     /// @param toTokenAddress The token to buy and transfer to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded addresses of the "from" token and Balancer pool. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // Decode the bridge data. | ||||
|         (address fromTokenAddress, address poolAddress) = abi.decode( | ||||
|             bridgeData, | ||||
|             (address, address) | ||||
|         ); | ||||
|         require(toTokenAddress != fromTokenAddress, "BalancerBridge/INVALID_PAIR"); | ||||
|  | ||||
|         uint256 fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this)); | ||||
|         // Grant an allowance to the exchange to spend `fromTokenAddress` token. | ||||
|         LibERC20Token.approveIfBelow(fromTokenAddress, poolAddress, fromTokenBalance); | ||||
|  | ||||
|         // Sell all of this contract's `fromTokenAddress` token balance. | ||||
|         (uint256 boughtAmount,) = IBalancerPool(poolAddress).swapExactAmountIn( | ||||
|             fromTokenAddress, // tokenIn | ||||
|             fromTokenBalance, // tokenAmountIn | ||||
|             toTokenAddress,   // tokenOut | ||||
|             amount,           // minAmountOut | ||||
|             uint256(-1)       // maxPrice | ||||
|         ); | ||||
|  | ||||
|         // Transfer the converted `toToken`s to `to`. | ||||
|         LibERC20Token.transfer(toTokenAddress, to, boughtAmount); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Magic success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										144
									
								
								contracts/asset-proxy/contracts/src/bridges/BancorBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								contracts/asset-proxy/contracts/src/bridges/BancorBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
|  | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
| import "../interfaces/IBancorNetwork.sol"; | ||||
|  | ||||
|  | ||||
| contract BancorBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     struct TransferState { | ||||
|         address bancorNetworkAddress; | ||||
|         address[] path; | ||||
|         IEtherToken weth; | ||||
|     } | ||||
|  | ||||
|     /// @dev Bancor ETH pseudo-address. | ||||
|     address constant public BANCOR_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; | ||||
|  | ||||
|     // solhint-disable no-empty-blocks | ||||
|     /// @dev Payable fallback to receive ETH from Bancor/WETH. | ||||
|     function () | ||||
|         external | ||||
|         payable | ||||
|     { | ||||
|         // Poor man's receive in 0.5.9 | ||||
|         require(msg.data.length == 0); | ||||
|     } | ||||
|  | ||||
|     /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` | ||||
|     ///      token encoded in the bridge data, then transfers the bought | ||||
|     ///      tokens to `to`. | ||||
|     /// @param toTokenAddress The token to buy and transfer to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded conversion path addresses and Bancor network address | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // hold variables to get around stack depth limitations | ||||
|         TransferState memory state; | ||||
|         // Decode the bridge data. | ||||
|         ( | ||||
|             state.path, | ||||
|             state.bancorNetworkAddress | ||||
|         // solhint-disable indent | ||||
|         ) = abi.decode(bridgeData, (address[], address)); | ||||
|         // solhint-enable indent | ||||
|         state.weth = IEtherToken(_getWethAddress()); | ||||
|  | ||||
|         require(state.path.length >= 2, "BancorBridge/PATH_LENGTH_MUST_BE_GREATER_THAN_TWO"); | ||||
|  | ||||
|         // Grant an allowance to the Bancor Network to spend `fromTokenAddress` token. | ||||
|         uint256 fromTokenBalance; | ||||
|         uint256 payableAmount = 0; | ||||
|         // If it's ETH in the path then withdraw from WETH | ||||
|         // The Bancor path will have ETH as the 0xeee address | ||||
|         // Bancor expects to be paid in ETH not WETH | ||||
|         if (state.path[0] == BANCOR_ETH_ADDRESS) { | ||||
|             fromTokenBalance = state.weth.balanceOf(address(this)); | ||||
|             state.weth.withdraw(fromTokenBalance); | ||||
|             payableAmount = fromTokenBalance; | ||||
|         } else { | ||||
|             fromTokenBalance = IERC20Token(state.path[0]).balanceOf(address(this)); | ||||
|             LibERC20Token.approveIfBelow(state.path[0], state.bancorNetworkAddress, fromTokenBalance); | ||||
|         } | ||||
|  | ||||
|         // Convert the tokens | ||||
|         uint256 boughtAmount = IBancorNetwork(state.bancorNetworkAddress).convertByPath.value(payableAmount)( | ||||
|             state.path, // path originating with source token and terminating in destination token | ||||
|             fromTokenBalance, // amount of source token to trade | ||||
|             amount, // minimum amount of destination token expected to receive | ||||
|             state.path[state.path.length-1] == BANCOR_ETH_ADDRESS ? address(this) : to, // beneficiary | ||||
|             address(0), // affiliateAccount; no fee paid | ||||
|             0 // affiliateFee; no fee paid | ||||
|         ); | ||||
|  | ||||
|         if (state.path[state.path.length-1] == BANCOR_ETH_ADDRESS) { | ||||
|             state.weth.deposit.value(boughtAmount)(); | ||||
|             state.weth.transfer(to, boughtAmount); | ||||
|         } | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             state.path[0] == BANCOR_ETH_ADDRESS ? address(state.weth) : state.path[0], | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Magic success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										103
									
								
								contracts/asset-proxy/contracts/src/bridges/CreamBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								contracts/asset-proxy/contracts/src/bridges/CreamBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
|  | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
| import "../interfaces/IBalancerPool.sol"; | ||||
|  | ||||
|  | ||||
| contract CreamBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` | ||||
|     ///      token encoded in the bridge data, then transfers the bought | ||||
|     ///      tokens to `to`. | ||||
|     /// @param toTokenAddress The token to buy and transfer to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded addresses of the "from" token and Balancer pool. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // Decode the bridge data. | ||||
|         (address fromTokenAddress, address poolAddress) = abi.decode( | ||||
|             bridgeData, | ||||
|             (address, address) | ||||
|         ); | ||||
|         require(toTokenAddress != fromTokenAddress, "CreamBridge/INVALID_PAIR"); | ||||
|  | ||||
|         uint256 fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this)); | ||||
|         // Grant an allowance to the exchange to spend `fromTokenAddress` token. | ||||
|         LibERC20Token.approveIfBelow(fromTokenAddress, poolAddress, fromTokenBalance); | ||||
|  | ||||
|         // Sell all of this contract's `fromTokenAddress` token balance. | ||||
|         (uint256 boughtAmount,) = IBalancerPool(poolAddress).swapExactAmountIn( | ||||
|             fromTokenAddress, // tokenIn | ||||
|             fromTokenBalance, // tokenAmountIn | ||||
|             toTokenAddress,   // tokenOut | ||||
|             amount,           // minAmountOut | ||||
|             uint256(-1)       // maxPrice | ||||
|         ); | ||||
|  | ||||
|         // Transfer the converted `toToken`s to `to`. | ||||
|         LibERC20Token.transfer(toTokenAddress, to, boughtAmount); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Magic success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										136
									
								
								contracts/asset-proxy/contracts/src/bridges/CryptoComBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								contracts/asset-proxy/contracts/src/bridges/CryptoComBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibAddressArray.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IUniswapV2Router01.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
|  | ||||
|  | ||||
| // solhint-disable space-after-comma | ||||
| // solhint-disable not-rely-on-time | ||||
| contract CryptoComBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     struct TransferState { | ||||
|         address[] path; | ||||
|         address router; | ||||
|         uint256 fromTokenBalance; | ||||
|     } | ||||
|  | ||||
|     /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` | ||||
|     ///      token encoded in the bridge data. | ||||
|     /// @param toTokenAddress The token to buy and transfer to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded path of token addresses. Last element must be toTokenAddress | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // hold variables to get around stack depth limitations | ||||
|         TransferState memory state; | ||||
|  | ||||
|         // Decode the bridge data to get the `fromTokenAddress`. | ||||
|         // solhint-disable indent | ||||
|         (state.path, state.router) = abi.decode(bridgeData, (address[], address)); | ||||
|         // solhint-enable indent | ||||
|  | ||||
|         require(state.path.length >= 2, "CryptoComBridge/PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | ||||
|         require(state.path[state.path.length - 1] == toTokenAddress, "CryptoComBridge/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"); | ||||
|  | ||||
|         // Just transfer the tokens if they're the same. | ||||
|         if (state.path[0] == toTokenAddress) { | ||||
|             LibERC20Token.transfer(state.path[0], to, amount); | ||||
|             return BRIDGE_SUCCESS; | ||||
|         } | ||||
|  | ||||
|         // Get our balance of `fromTokenAddress` token. | ||||
|         state.fromTokenBalance = IERC20Token(state.path[0]).balanceOf(address(this)); | ||||
|  | ||||
|         // Grant the SushiSwap router an allowance. | ||||
|         LibERC20Token.approveIfBelow( | ||||
|             state.path[0], | ||||
|             state.router, | ||||
|             state.fromTokenBalance | ||||
|         ); | ||||
|  | ||||
|         // Buy as much `toTokenAddress` token with `fromTokenAddress` token | ||||
|         // and transfer it to `to`. | ||||
|         IUniswapV2Router01 router = IUniswapV2Router01(state.router); | ||||
|         uint[] memory amounts = router.swapExactTokensForTokens( | ||||
|              // Sell all tokens we hold. | ||||
|             state.fromTokenBalance, | ||||
|              // Minimum buy amount. | ||||
|             amount, | ||||
|             // Convert `fromTokenAddress` to `toTokenAddress`. | ||||
|             state.path, | ||||
|             // Recipient is `to`. | ||||
|             to, | ||||
|             // Expires after this block. | ||||
|             block.timestamp | ||||
|         ); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             // input token | ||||
|             state.path[0], | ||||
|             // output token | ||||
|             toTokenAddress, | ||||
|             // input token amount | ||||
|             state.fromTokenBalance, | ||||
|             // output token amount | ||||
|             amounts[amounts.length - 1], | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|  | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
| @@ -35,18 +35,27 @@ contract CurveBridge is | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     struct CurveBridgeData { | ||||
|         address curveAddress; | ||||
|         bytes4 exchangeFunctionSelector; | ||||
|         address fromTokenAddress; | ||||
|         int128 fromCoinIdx; | ||||
|         int128 toCoinIdx; | ||||
|     } | ||||
|  | ||||
|     /// @dev Callback for `ICurve`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the opposing asset | ||||
|     ///      (DAI, USDC) to the Curve contract, then transfers the bought | ||||
|     ///      tokens to `to`. | ||||
|     /// @param toTokenAddress The token to give to `to` (i.e DAI, USDC, USDT). | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoeded "from" token address. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address /* from */, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
| @@ -55,40 +64,42 @@ contract CurveBridge is | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // Decode the bridge data to get the Curve metadata. | ||||
|         (address curveAddress, int128 fromCoinIdx, int128 toCoinIdx, int128 version) = abi.decode(bridgeData, (address, int128, int128, int128)); | ||||
|         ICurve exchange = ICurve(curveAddress); | ||||
|         CurveBridgeData memory data = abi.decode(bridgeData, (CurveBridgeData)); | ||||
|  | ||||
|         address fromTokenAddress = exchange.underlying_coins(fromCoinIdx); | ||||
|         require(toTokenAddress != fromTokenAddress, "CurveBridge/INVALID_PAIR"); | ||||
|         require(toTokenAddress != data.fromTokenAddress, "CurveBridge/INVALID_PAIR"); | ||||
|         uint256 fromTokenBalance = IERC20Token(data.fromTokenAddress).balanceOf(address(this)); | ||||
|         // Grant an allowance to the exchange to spend `fromTokenAddress` token. | ||||
|         LibERC20Token.approve(fromTokenAddress, address(exchange), uint256(-1)); | ||||
|         LibERC20Token.approveIfBelow(data.fromTokenAddress, data.curveAddress, fromTokenBalance); | ||||
|  | ||||
|         // Try to sell all of this contract's `fromTokenAddress` token balance. | ||||
|         if (version == 0) { | ||||
|             exchange.exchange_underlying( | ||||
|                 fromCoinIdx, | ||||
|                 toCoinIdx, | ||||
|                 // dx | ||||
|                 IERC20Token(fromTokenAddress).balanceOf(address(this)), | ||||
|                 // min dy | ||||
|                 amount, | ||||
|                 // expires | ||||
|                 block.timestamp + 1 | ||||
|             ); | ||||
|         } else { | ||||
|             exchange.exchange_underlying( | ||||
|                 fromCoinIdx, | ||||
|                 toCoinIdx, | ||||
|                 // dx | ||||
|                 IERC20Token(fromTokenAddress).balanceOf(address(this)), | ||||
|                 // min dy | ||||
|                 amount | ||||
|             ); | ||||
|         { | ||||
|             (bool didSucceed, bytes memory resultData) = | ||||
|                 data.curveAddress.call(abi.encodeWithSelector( | ||||
|                     data.exchangeFunctionSelector, | ||||
|                     data.fromCoinIdx, | ||||
|                     data.toCoinIdx, | ||||
|                     // dx | ||||
|                     fromTokenBalance, | ||||
|                     // min dy | ||||
|                     amount | ||||
|                 )); | ||||
|             if (!didSucceed) { | ||||
|                 assembly { revert(add(resultData, 32), mload(resultData)) } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         uint256 toTokenBalance = IERC20Token(toTokenAddress).balanceOf(address(this)); | ||||
|         // Transfer the converted `toToken`s to `to`. | ||||
|         LibERC20Token.transfer(toTokenAddress, to, toTokenBalance); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             data.fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             toTokenBalance, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										147
									
								
								contracts/asset-proxy/contracts/src/bridges/DODOBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								contracts/asset-proxy/contracts/src/bridges/DODOBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
|  | ||||
|  | ||||
| interface IDODOHelper { | ||||
|  | ||||
|     function querySellQuoteToken(address dodo, uint256 amount) external view returns (uint256); | ||||
| } | ||||
|  | ||||
|  | ||||
| interface IDODO { | ||||
|  | ||||
|     function sellBaseToken(uint256 amount, uint256 minReceiveQuote, bytes calldata data) external returns (uint256); | ||||
|  | ||||
|     function buyBaseToken(uint256 amount, uint256 maxPayQuote, bytes calldata data) external returns (uint256); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| contract DODOBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|  | ||||
|     struct TransferState { | ||||
|         address fromTokenAddress; | ||||
|         uint256 fromTokenBalance; | ||||
|         address pool; | ||||
|         bool isSellBase; | ||||
|     } | ||||
|  | ||||
|     /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` | ||||
|     ///      token encoded in the bridge data. | ||||
|     /// @param toTokenAddress The token to buy and transfer to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded path of token addresses. Last element must be toTokenAddress | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         TransferState memory state; | ||||
|         // Decode the bridge data to get the `fromTokenAddress`. | ||||
|         (state.fromTokenAddress, state.pool, state.isSellBase) = abi.decode(bridgeData, (address, address, bool)); | ||||
|         require(state.pool != address(0), "DODOBridge/InvalidPool"); | ||||
|         IDODO exchange = IDODO(state.pool); | ||||
|         // Get our balance of `fromTokenAddress` token. | ||||
|         state.fromTokenBalance = IERC20Token(state.fromTokenAddress).balanceOf(address(this)); | ||||
|  | ||||
|         // Grant the pool an allowance. | ||||
|         LibERC20Token.approveIfBelow( | ||||
|             state.fromTokenAddress, | ||||
|             address(exchange), | ||||
|             state.fromTokenBalance | ||||
|         ); | ||||
|  | ||||
|         uint256 boughtAmount; | ||||
|         if (state.isSellBase) { | ||||
|             boughtAmount = exchange.sellBaseToken( | ||||
|                 // amount to sell | ||||
|                 state.fromTokenBalance, | ||||
|                 // min receive amount | ||||
|                 1, | ||||
|                 new bytes(0) | ||||
|             ); | ||||
|         } else { | ||||
|             // Need to re-calculate the sell quote amount into buyBase | ||||
|             boughtAmount = IDODOHelper(_getDODOHelperAddress()).querySellQuoteToken( | ||||
|                 address(exchange), | ||||
|                 state.fromTokenBalance | ||||
|             ); | ||||
|             exchange.buyBaseToken( | ||||
|                 // amount to buy | ||||
|                 boughtAmount, | ||||
|                 // max pay amount | ||||
|                 state.fromTokenBalance, | ||||
|                 new bytes(0) | ||||
|             ); | ||||
|         } | ||||
|         // Transfer funds to `to` | ||||
|         IERC20Token(toTokenAddress).transfer(to, boughtAmount); | ||||
|  | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             // input token | ||||
|             state.fromTokenAddress, | ||||
|             // output token | ||||
|             toTokenAddress, | ||||
|             // input token amount | ||||
|             state.fromTokenBalance, | ||||
|             // output token amount | ||||
|             boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|  | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,200 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibBytes.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
| import "./MixinGasToken.sol"; | ||||
|  | ||||
|  | ||||
| // solhint-disable space-after-comma, indent | ||||
| contract DexForwarderBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants, | ||||
|     MixinGasToken | ||||
| { | ||||
|     using LibSafeMath for uint256; | ||||
|  | ||||
|     /// @dev Data needed to reconstruct a bridge call. | ||||
|     struct BridgeCall { | ||||
|         address target; | ||||
|         uint256 inputTokenAmount; | ||||
|         uint256 outputTokenAmount; | ||||
|         bytes bridgeData; | ||||
|     } | ||||
|  | ||||
|     /// @dev Intermediate state variables used by `bridgeTransferFrom()`, in | ||||
|     ///      struct form to get around stack limits. | ||||
|     struct TransferFromState { | ||||
|         address inputToken; | ||||
|         uint256 initialInputTokenBalance; | ||||
|         uint256 callInputTokenAmount; | ||||
|         uint256 callOutputTokenAmount; | ||||
|         uint256 totalInputTokenSold; | ||||
|         BridgeCall[] calls; | ||||
|     } | ||||
|  | ||||
|     /// @dev Spends this contract's entire balance of input tokens by forwarding | ||||
|     /// them to other bridges. Reverts if the entire balance is not spent. | ||||
|     /// @param outputToken The token being bought. | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param bridgeData The abi-encoded input token address. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address outputToken, | ||||
|         address /* from */, | ||||
|         address to, | ||||
|         uint256 /* amount */, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         freesGasTokensFromCollector | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         require( | ||||
|             msg.sender == _getERC20BridgeProxyAddress(), | ||||
|             "DexForwarderBridge/SENDER_NOT_AUTHORIZED" | ||||
|         ); | ||||
|         TransferFromState memory state; | ||||
|         ( | ||||
|             state.inputToken, | ||||
|             state.calls | ||||
|         ) = abi.decode(bridgeData, (address, BridgeCall[])); | ||||
|  | ||||
|         state.initialInputTokenBalance = | ||||
|             IERC20Token(state.inputToken).balanceOf(address(this)); | ||||
|  | ||||
|         for (uint256 i = 0; i < state.calls.length; ++i) { | ||||
|             // Stop if the we've sold all our input tokens. | ||||
|             if (state.totalInputTokenSold >= state.initialInputTokenBalance) { | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             // Compute token amounts. | ||||
|             state.callInputTokenAmount = LibSafeMath.min256( | ||||
|                 state.calls[i].inputTokenAmount, | ||||
|                 state.initialInputTokenBalance.safeSub(state.totalInputTokenSold) | ||||
|             ); | ||||
|             state.callOutputTokenAmount = LibMath.getPartialAmountFloor( | ||||
|                 state.callInputTokenAmount, | ||||
|                 state.calls[i].inputTokenAmount, | ||||
|                 state.calls[i].outputTokenAmount | ||||
|             ); | ||||
|  | ||||
|             // Execute the call in a new context so we can recoup transferred | ||||
|             // funds by reverting. | ||||
|             (bool didSucceed, ) = address(this) | ||||
|                 .call(abi.encodeWithSelector( | ||||
|                     this.executeBridgeCall.selector, | ||||
|                     state.calls[i].target, | ||||
|                     to, | ||||
|                     state.inputToken, | ||||
|                     outputToken, | ||||
|                     state.callInputTokenAmount, | ||||
|                     state.callOutputTokenAmount, | ||||
|                     state.calls[i].bridgeData | ||||
|                 )); | ||||
|  | ||||
|             if (didSucceed) { | ||||
|                 // Increase the amount of tokens sold. | ||||
|                 state.totalInputTokenSold = state.totalInputTokenSold.safeAdd( | ||||
|                     state.callInputTokenAmount | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|         // Always succeed. | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev Transfers `inputToken` token to a bridge contract then calls | ||||
|     ///      its `bridgeTransferFrom()`. This is executed in separate context | ||||
|     ///      so we can revert the transfer on error. This can only be called | ||||
|     //       by this contract itself. | ||||
|     /// @param bridge The bridge contract. | ||||
|     /// @param to The recipient of `outputToken` tokens. | ||||
|     /// @param inputToken The input token. | ||||
|     /// @param outputToken The output token. | ||||
|     /// @param inputTokenAmount The amount of input tokens to transfer to `bridge`. | ||||
|     /// @param outputTokenAmount The amount of expected output tokens to be sent | ||||
|     ///        to `to` by `bridge`. | ||||
|     function executeBridgeCall( | ||||
|         address bridge, | ||||
|         address to, | ||||
|         address inputToken, | ||||
|         address outputToken, | ||||
|         uint256 inputTokenAmount, | ||||
|         uint256 outputTokenAmount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|     { | ||||
|         // Must be called through `bridgeTransferFrom()`. | ||||
|         require(msg.sender == address(this), "DexForwarderBridge/ONLY_SELF"); | ||||
|         // `bridge` must not be this contract. | ||||
|         require(bridge != address(this)); | ||||
|  | ||||
|         // Get the starting balance of output tokens for `to`. | ||||
|         uint256 initialRecipientBalance = IERC20Token(outputToken).balanceOf(to); | ||||
|  | ||||
|         // Transfer input tokens to the bridge. | ||||
|         LibERC20Token.transfer(inputToken, bridge, inputTokenAmount); | ||||
|  | ||||
|         // Call the bridge. | ||||
|         (bool didSucceed, bytes memory resultData) = | ||||
|             bridge.call(abi.encodeWithSelector( | ||||
|                 IERC20Bridge(0).bridgeTransferFrom.selector, | ||||
|                 outputToken, | ||||
|                 bridge, | ||||
|                 to, | ||||
|                 outputTokenAmount, | ||||
|                 bridgeData | ||||
|             )); | ||||
|  | ||||
|         // Revert if the call failed or not enough tokens were bought. | ||||
|         // This will also undo the token transfer. | ||||
|         require( | ||||
|             didSucceed | ||||
|             && resultData.length == 32 | ||||
|             && LibBytes.readBytes32(resultData, 0) == bytes32(BRIDGE_SUCCESS) | ||||
|             && IERC20Token(outputToken).balanceOf(to).safeSub(initialRecipientBalance) >= outputTokenAmount | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Magic success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
| @@ -50,7 +50,7 @@ contract DydxBridge is | ||||
|     /// @param encodedBridgeData An abi-encoded `BridgeData` struct. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address, | ||||
|         address, /* toTokenAddress */ | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
| @@ -81,6 +81,7 @@ contract DydxBridge is | ||||
|  | ||||
|         // Run operation. This will revert on failure. | ||||
|         IDydx(_getDydxAddress()).operate(accounts, actions); | ||||
|  | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -38,13 +38,14 @@ contract Eth2DaiBridge is | ||||
|     ///      (DAI or WETH) to the Eth2Dai contract, then transfers the bought | ||||
|     ///      tokens to `to`. | ||||
|     /// @param toTokenAddress The token to give to `to` (either DAI or WETH). | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoeded "from" token address. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address /* from */, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
| @@ -56,18 +57,28 @@ contract Eth2DaiBridge is | ||||
|         (address fromTokenAddress) = abi.decode(bridgeData, (address)); | ||||
|  | ||||
|         IEth2Dai exchange = IEth2Dai(_getEth2DaiAddress()); | ||||
|         uint256 fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this)); | ||||
|         // Grant an allowance to the exchange to spend `fromTokenAddress` token. | ||||
|         LibERC20Token.approve(fromTokenAddress, address(exchange), uint256(-1)); | ||||
|         LibERC20Token.approveIfBelow(fromTokenAddress, address(exchange), fromTokenBalance); | ||||
|  | ||||
|         // Try to sell all of this contract's `fromTokenAddress` token balance. | ||||
|         uint256 boughtAmount = exchange.sellAllAmount( | ||||
|             fromTokenAddress, | ||||
|             IERC20Token(fromTokenAddress).balanceOf(address(this)), | ||||
|             fromTokenBalance, | ||||
|             toTokenAddress, | ||||
|             amount | ||||
|         ); | ||||
|         // Transfer the converted `toToken`s to `to`. | ||||
|         LibERC20Token.transfer(toTokenAddress, to, boughtAmount); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2019 ZeroEx Intl. | ||||
|   Copyright 2020 ZeroEx Intl. | ||||
|  | ||||
|   Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|   you may not use this file except in compliance with the License. | ||||
| @@ -45,6 +45,7 @@ contract KyberBridge is | ||||
|         uint256 fromTokenBalance; | ||||
|         uint256 payableAmount; | ||||
|         uint256 conversionRate; | ||||
|         bytes hint; | ||||
|     } | ||||
|  | ||||
|     /// @dev Kyber ETH pseudo-address. | ||||
| @@ -55,24 +56,28 @@ contract KyberBridge is | ||||
|     uint256 constant private KYBER_RATE_BASE = 10 ** 18; | ||||
|  | ||||
|     // solhint-disable no-empty-blocks | ||||
|     /// @dev Payable fallback to receive ETH from Kyber. | ||||
|     /// @dev Payable fallback to receive ETH from Kyber/WETH. | ||||
|     function () | ||||
|         external | ||||
|         payable | ||||
|     {} | ||||
|     { | ||||
|         // Poor man's receive in 0.5.9 | ||||
|         require(msg.data.length == 0); | ||||
|     } | ||||
|  | ||||
|     /// @dev Callback for `IKyberBridge`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the opposing asset | ||||
|     ///      to the `KyberNetworkProxy` contract, then transfers the bought | ||||
|     ///      tokens to `to`. | ||||
|     /// @param toTokenAddress The token to give to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoeded "from" token address. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address /* from */, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
| @@ -84,43 +89,35 @@ contract KyberBridge is | ||||
|         state.kyber = IKyberNetworkProxy(_getKyberNetworkProxyAddress()); | ||||
|         state.weth = IEtherToken(_getWethAddress()); | ||||
|         // Decode the bridge data to get the `fromTokenAddress`. | ||||
|         (state.fromTokenAddress) = abi.decode(bridgeData, (address)); | ||||
|         (state.fromTokenAddress, state.hint) = abi.decode(bridgeData, (address, bytes)); | ||||
|         // Query the balance of "from" tokens. | ||||
|         state.fromTokenBalance = IERC20Token(state.fromTokenAddress).balanceOf(address(this)); | ||||
|         if (state.fromTokenBalance == 0) { | ||||
|             // Return failure if no input tokens. | ||||
|             return BRIDGE_FAILED; | ||||
|         } | ||||
|         // Compute the conversion rate, expressed in 18 decimals. | ||||
|         // The sequential notation is to get around stack limits. | ||||
|         state.conversionRate = KYBER_RATE_BASE; | ||||
|         state.conversionRate = state.conversionRate.safeMul(amount); | ||||
|         state.conversionRate = state.conversionRate.safeMul( | ||||
|             10 ** uint256(LibERC20Token.decimals(state.fromTokenAddress)) | ||||
|         ); | ||||
|         state.conversionRate = state.conversionRate.safeDiv(state.fromTokenBalance); | ||||
|         state.conversionRate = state.conversionRate.safeDiv( | ||||
|             10 ** uint256(LibERC20Token.decimals(toTokenAddress)) | ||||
|         ); | ||||
|         if (state.fromTokenAddress == toTokenAddress) { | ||||
|             // Just transfer the tokens if they're the same. | ||||
|             LibERC20Token.transfer(state.fromTokenAddress, to, state.fromTokenBalance); | ||||
|             return BRIDGE_SUCCESS; | ||||
|         } else if (state.fromTokenAddress != address(state.weth)) { | ||||
|             // If the input token is not WETH, grant an allowance to the exchange | ||||
|             // to spend them. | ||||
|             LibERC20Token.approve(state.fromTokenAddress, address(state.kyber), uint256(-1)); | ||||
|         } else { | ||||
|             // If the input token is WETH, unwrap it and attach it to the call. | ||||
|         } | ||||
|         if (state.fromTokenAddress == address(state.weth)) { | ||||
|             // From WETH | ||||
|             state.fromTokenAddress = KYBER_ETH_ADDRESS; | ||||
|             state.payableAmount = state.fromTokenBalance; | ||||
|             state.weth.withdraw(state.fromTokenBalance); | ||||
|         } else { | ||||
|             LibERC20Token.approveIfBelow( | ||||
|                 state.fromTokenAddress, | ||||
|                 address(state.kyber), | ||||
|                 state.fromTokenBalance | ||||
|             ); | ||||
|         } | ||||
|         bool isToTokenWeth = toTokenAddress == address(state.weth); | ||||
|  | ||||
|         // Try to sell all of this contract's input token balance through | ||||
|         // `KyberNetworkProxy.trade()`. | ||||
|         uint256 boughtAmount = state.kyber.trade.value(state.payableAmount)( | ||||
|         uint256 boughtAmount = state.kyber.tradeWithHint.value(state.payableAmount)( | ||||
|             // Input token. | ||||
|             state.fromTokenAddress, | ||||
|             // Sell amount. | ||||
| @@ -132,17 +129,26 @@ contract KyberBridge is | ||||
|             isToTokenWeth ? address(uint160(address(this))) : address(uint160(to)), | ||||
|             // Buy as much as possible. | ||||
|             uint256(-1), | ||||
|             // Compute the minimum conversion rate, which is expressed in units with | ||||
|             // 18 decimal places. | ||||
|             state.conversionRate, | ||||
|             // The minimum conversion rate | ||||
|             1, | ||||
|             // No affiliate address. | ||||
|             address(0) | ||||
|             address(0), | ||||
|             state.hint | ||||
|         ); | ||||
|         // Wrap ETH output and transfer to recipient. | ||||
|         if (isToTokenWeth) { | ||||
|             state.weth.deposit.value(boughtAmount)(); | ||||
|             state.weth.transfer(to, boughtAmount); | ||||
|         } | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             state.fromTokenAddress == KYBER_ETH_ADDRESS ? address(state.weth) : state.fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             state.fromTokenBalance, | ||||
|             boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
| @@ -159,4 +165,5 @@ contract KyberBridge is | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,94 @@ | ||||
| /* | ||||
|  | ||||
|   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.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
| import "../interfaces/IMStable.sol"; | ||||
|  | ||||
|  | ||||
| contract MStableBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|  | ||||
|     /// @dev Swaps specified tokens against the mStable mUSD contract | ||||
|     /// @param toTokenAddress The token to give to `to` (i.e DAI, USDC, USDT). | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded "from" token address. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     // solhint-disable no-unused-vars | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // Decode the bridge data to get the `fromTokenAddress`. | ||||
|         (address fromTokenAddress) = abi.decode(bridgeData, (address)); | ||||
|  | ||||
|         IMStable exchange = IMStable(_getMUsdAddress()); | ||||
|         uint256 fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this)); | ||||
|         // Grant an allowance to the exchange to spend `fromTokenAddress` token. | ||||
|         LibERC20Token.approveIfBelow(fromTokenAddress, address(exchange), fromTokenBalance); | ||||
|  | ||||
|         // Try to sell all of this contract's `fromTokenAddress` token balance. | ||||
|         uint256 boughtAmount = exchange.swap( | ||||
|             fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             to | ||||
|         ); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Magic success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,55 @@ | ||||
| /* | ||||
|  | ||||
|   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.16; | ||||
|  | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IGasToken.sol"; | ||||
|  | ||||
|  | ||||
| contract MixinGasToken is | ||||
|     DeploymentConstants | ||||
| { | ||||
|  | ||||
|     /// @dev Frees gas tokens based on the amount of gas consumed in the function | ||||
|     modifier freesGasTokens { | ||||
|         uint256 gasBefore = gasleft(); | ||||
|         _; | ||||
|         IGasToken gst = IGasToken(_getGstAddress()); | ||||
|         if (address(gst) != address(0)) { | ||||
|             // (gasUsed + FREE_BASE) / (2 * REIMBURSE - FREE_TOKEN) | ||||
|             //            14154             24000        6870 | ||||
|             uint256 value = (gasBefore - gasleft() + 14154) / 41130; | ||||
|             gst.freeUpTo(value); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Frees gas tokens using the balance of `from`. Amount freed is based | ||||
|     ///     on the gas consumed in the function | ||||
|     modifier freesGasTokensFromCollector() { | ||||
|         uint256 gasBefore = gasleft(); | ||||
|         _; | ||||
|         IGasToken gst = IGasToken(_getGstAddress()); | ||||
|         if (address(gst) != address(0)) { | ||||
|             // (gasUsed + FREE_BASE) / (2 * REIMBURSE - FREE_TOKEN) | ||||
|             //            14154             24000        6870 | ||||
|             uint256 value = (gasBefore - gasleft() + 14154) / 41130; | ||||
|             gst.freeFromUpTo(_getGstCollectorAddress(), value); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										148
									
								
								contracts/asset-proxy/contracts/src/bridges/MooniswapBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								contracts/asset-proxy/contracts/src/bridges/MooniswapBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
| import "../interfaces/IMooniswap.sol"; | ||||
|  | ||||
|  | ||||
| // solhint-disable space-after-comma | ||||
| // solhint-disable not-rely-on-time | ||||
| contract MooniswapBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|  | ||||
|     struct TransferState { | ||||
|         IMooniswap pool; | ||||
|         uint256 fromTokenBalance; | ||||
|         IEtherToken weth; | ||||
|         uint256 boughtAmount; | ||||
|         address fromTokenAddress; | ||||
|         address toTokenAddress; | ||||
|     } | ||||
|  | ||||
|     // solhint-disable no-empty-blocks | ||||
|     /// @dev Payable fallback to receive ETH from uniswap. | ||||
|     function () | ||||
|         external | ||||
|         payable | ||||
|     {} | ||||
|  | ||||
|     /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` | ||||
|     ///      token encoded in the bridge data. | ||||
|     /// @param toTokenAddress The token to buy and transfer to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded path of token addresses. Last element must be toTokenAddress | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // State memory object to avoid stack overflows. | ||||
|         TransferState memory state; | ||||
|         // Decode the bridge data to get the `fromTokenAddress`. | ||||
|         address fromTokenAddress = abi.decode(bridgeData, (address)); | ||||
|         // Get the weth contract. | ||||
|         state.weth = IEtherToken(_getWethAddress()); | ||||
|         // Get our balance of `fromTokenAddress` token. | ||||
|         state.fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this)); | ||||
|  | ||||
|         state.fromTokenAddress = fromTokenAddress == address(state.weth) ? address(0) : fromTokenAddress; | ||||
|         state.toTokenAddress = toTokenAddress == address(state.weth) ? address(0) : toTokenAddress; | ||||
|         state.pool = IMooniswap( | ||||
|             IMooniswapRegistry(_getMooniswapAddress()).pools( | ||||
|                 state.fromTokenAddress, | ||||
|                 state.toTokenAddress | ||||
|             ) | ||||
|         ); | ||||
|  | ||||
|         // withdraw WETH to ETH | ||||
|         if (state.fromTokenAddress == address(0)) { | ||||
|             state.weth.withdraw(state.fromTokenBalance); | ||||
|         } else { | ||||
|             // Grant the pool an allowance. | ||||
|             LibERC20Token.approveIfBelow( | ||||
|                 state.fromTokenAddress, | ||||
|                 address(state.pool), | ||||
|                 state.fromTokenBalance | ||||
|             ); | ||||
|         } | ||||
|         uint256 ethValue = state.fromTokenAddress == address(0) ? state.fromTokenBalance : 0; | ||||
|         state.boughtAmount = state.pool.swap.value(ethValue)( | ||||
|             state.fromTokenAddress, | ||||
|             state.toTokenAddress, | ||||
|             state.fromTokenBalance, | ||||
|             amount, | ||||
|             address(0) | ||||
|         ); | ||||
|         // Deposit to WETH | ||||
|         if (state.toTokenAddress == address(0)) { | ||||
|             state.weth.deposit.value(state.boughtAmount)(); | ||||
|         } | ||||
|  | ||||
|         // Transfer funds to `to` | ||||
|         LibERC20Token.transfer(toTokenAddress, to, state.boughtAmount); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             // input token | ||||
|             fromTokenAddress, | ||||
|             // output token | ||||
|             toTokenAddress, | ||||
|             // input token amount | ||||
|             state.fromTokenBalance, | ||||
|             // output token amount | ||||
|             state.boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|  | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										95
									
								
								contracts/asset-proxy/contracts/src/bridges/ShellBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								contracts/asset-proxy/contracts/src/bridges/ShellBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| /* | ||||
|  | ||||
|   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.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
| import "../interfaces/IShell.sol"; | ||||
|  | ||||
|  | ||||
| contract ShellBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|  | ||||
|     /// @dev Swaps specified tokens against the Shell contract | ||||
|     /// @param toTokenAddress The token to give to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded "from" token address. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     // solhint-disable no-unused-vars | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // Decode the bridge data to get the `fromTokenAddress` and `pool`. | ||||
|         (address fromTokenAddress, address pool) = abi.decode(bridgeData, (address, address)); | ||||
|  | ||||
|         uint256 fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this)); | ||||
|         // Grant an allowance to the exchange to spend `fromTokenAddress` token. | ||||
|         LibERC20Token.approveIfBelow(fromTokenAddress, pool, fromTokenBalance); | ||||
|  | ||||
|         // Try to sell all of this contract's `fromTokenAddress` token balance. | ||||
|         uint256 boughtAmount = IShell(pool).originSwap( | ||||
|             fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             amount, // min amount | ||||
|             block.timestamp + 1 | ||||
|         ); | ||||
|         LibERC20Token.transfer(toTokenAddress, to, boughtAmount); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Magic success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										119
									
								
								contracts/asset-proxy/contracts/src/bridges/SnowSwapBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								contracts/asset-proxy/contracts/src/bridges/SnowSwapBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
|  | ||||
| /* | ||||
|  | ||||
|   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.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
| import "../interfaces/ICurve.sol"; | ||||
|  | ||||
|  | ||||
| // solhint-disable not-rely-on-time | ||||
| // solhint-disable space-after-comma | ||||
| contract SnowSwapBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     struct SnowSwapBridgeData { | ||||
|         address curveAddress; | ||||
|         bytes4 exchangeFunctionSelector; | ||||
|         address fromTokenAddress; | ||||
|         int128 fromCoinIdx; | ||||
|         int128 toCoinIdx; | ||||
|     } | ||||
|  | ||||
|     /// @dev Callback for `ICurve`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the opposing asset | ||||
|     ///      (DAI, USDC) to the Curve contract, then transfers the bought | ||||
|     ///      tokens to `to`. | ||||
|     /// @param toTokenAddress The token to give to `to` (i.e DAI, USDC, USDT). | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoeded "from" token address. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // Decode the bridge data to get the SnowSwap metadata. | ||||
|         SnowSwapBridgeData memory data = abi.decode(bridgeData, (SnowSwapBridgeData)); | ||||
|  | ||||
|         require(toTokenAddress != data.fromTokenAddress, "SnowSwapBridge/INVALID_PAIR"); | ||||
|         uint256 fromTokenBalance = IERC20Token(data.fromTokenAddress).balanceOf(address(this)); | ||||
|         // Grant an allowance to the exchange to spend `fromTokenAddress` token. | ||||
|         LibERC20Token.approveIfBelow(data.fromTokenAddress, data.curveAddress, fromTokenBalance); | ||||
|  | ||||
|         // Try to sell all of this contract's `fromTokenAddress` token balance. | ||||
|         { | ||||
|             (bool didSucceed, bytes memory resultData) = | ||||
|                 data.curveAddress.call(abi.encodeWithSelector( | ||||
|                     data.exchangeFunctionSelector, | ||||
|                     data.fromCoinIdx, | ||||
|                     data.toCoinIdx, | ||||
|                     // dx | ||||
|                     fromTokenBalance, | ||||
|                     // min dy | ||||
|                     amount | ||||
|                 )); | ||||
|             if (!didSucceed) { | ||||
|                 assembly { revert(add(resultData, 32), mload(resultData)) } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         uint256 toTokenBalance = IERC20Token(toTokenAddress).balanceOf(address(this)); | ||||
|         // Transfer the converted `toToken`s to `to`. | ||||
|         LibERC20Token.transfer(toTokenAddress, to, toTokenBalance); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             data.fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             toTokenBalance, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Magic success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										136
									
								
								contracts/asset-proxy/contracts/src/bridges/SushiSwapBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								contracts/asset-proxy/contracts/src/bridges/SushiSwapBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibAddressArray.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IUniswapV2Router01.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
|  | ||||
|  | ||||
| // solhint-disable space-after-comma | ||||
| // solhint-disable not-rely-on-time | ||||
| contract SushiSwapBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     struct TransferState { | ||||
|         address[] path; | ||||
|         address router; | ||||
|         uint256 fromTokenBalance; | ||||
|     } | ||||
|  | ||||
|     /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` | ||||
|     ///      token encoded in the bridge data. | ||||
|     /// @param toTokenAddress The token to buy and transfer to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded path of token addresses. Last element must be toTokenAddress | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // hold variables to get around stack depth limitations | ||||
|         TransferState memory state; | ||||
|  | ||||
|         // Decode the bridge data to get the `fromTokenAddress`. | ||||
|         // solhint-disable indent | ||||
|         (state.path, state.router) = abi.decode(bridgeData, (address[], address)); | ||||
|         // solhint-enable indent | ||||
|  | ||||
|         require(state.path.length >= 2, "SushiSwapBridge/PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | ||||
|         require(state.path[state.path.length - 1] == toTokenAddress, "SushiSwapBridge/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"); | ||||
|  | ||||
|         // Just transfer the tokens if they're the same. | ||||
|         if (state.path[0] == toTokenAddress) { | ||||
|             LibERC20Token.transfer(state.path[0], to, amount); | ||||
|             return BRIDGE_SUCCESS; | ||||
|         } | ||||
|  | ||||
|         // Get our balance of `fromTokenAddress` token. | ||||
|         state.fromTokenBalance = IERC20Token(state.path[0]).balanceOf(address(this)); | ||||
|  | ||||
|         // Grant the SushiSwap router an allowance. | ||||
|         LibERC20Token.approveIfBelow( | ||||
|             state.path[0], | ||||
|             state.router, | ||||
|             state.fromTokenBalance | ||||
|         ); | ||||
|  | ||||
|         // Buy as much `toTokenAddress` token with `fromTokenAddress` token | ||||
|         // and transfer it to `to`. | ||||
|         IUniswapV2Router01 router = IUniswapV2Router01(state.router); | ||||
|         uint[] memory amounts = router.swapExactTokensForTokens( | ||||
|              // Sell all tokens we hold. | ||||
|             state.fromTokenBalance, | ||||
|              // Minimum buy amount. | ||||
|             amount, | ||||
|             // Convert `fromTokenAddress` to `toTokenAddress`. | ||||
|             state.path, | ||||
|             // Recipient is `to`. | ||||
|             to, | ||||
|             // Expires after this block. | ||||
|             block.timestamp | ||||
|         ); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             // input token | ||||
|             state.path[0], | ||||
|             // output token | ||||
|             toTokenAddress, | ||||
|             // input token amount | ||||
|             state.fromTokenBalance, | ||||
|             // output token amount | ||||
|             amounts[amounts.length - 1], | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|  | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										119
									
								
								contracts/asset-proxy/contracts/src/bridges/SwerveBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								contracts/asset-proxy/contracts/src/bridges/SwerveBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
|  | ||||
| /* | ||||
|  | ||||
|   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.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
| import "../interfaces/ICurve.sol"; | ||||
|  | ||||
|  | ||||
| // solhint-disable not-rely-on-time | ||||
| // solhint-disable space-after-comma | ||||
| contract SwerveBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     struct SwerveBridgeData { | ||||
|         address curveAddress; | ||||
|         bytes4 exchangeFunctionSelector; | ||||
|         address fromTokenAddress; | ||||
|         int128 fromCoinIdx; | ||||
|         int128 toCoinIdx; | ||||
|     } | ||||
|  | ||||
|     /// @dev Callback for `ICurve`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the opposing asset | ||||
|     ///      (DAI, USDC) to the Curve contract, then transfers the bought | ||||
|     ///      tokens to `to`. | ||||
|     /// @param toTokenAddress The token to give to `to` (i.e DAI, USDC, USDT). | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoeded "from" token address. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // Decode the bridge data to get the SwerveBridgeData metadata. | ||||
|         SwerveBridgeData memory data = abi.decode(bridgeData, (SwerveBridgeData)); | ||||
|  | ||||
|         require(toTokenAddress != data.fromTokenAddress, "SwerveBridge/INVALID_PAIR"); | ||||
|         uint256 fromTokenBalance = IERC20Token(data.fromTokenAddress).balanceOf(address(this)); | ||||
|         // Grant an allowance to the exchange to spend `fromTokenAddress` token. | ||||
|         LibERC20Token.approveIfBelow(data.fromTokenAddress, data.curveAddress, fromTokenBalance); | ||||
|  | ||||
|         // Try to sell all of this contract's `fromTokenAddress` token balance. | ||||
|         { | ||||
|             (bool didSucceed, bytes memory resultData) = | ||||
|                 data.curveAddress.call(abi.encodeWithSelector( | ||||
|                     data.exchangeFunctionSelector, | ||||
|                     data.fromCoinIdx, | ||||
|                     data.toCoinIdx, | ||||
|                     // dx | ||||
|                     fromTokenBalance, | ||||
|                     // min dy | ||||
|                     amount | ||||
|                 )); | ||||
|             if (!didSucceed) { | ||||
|                 assembly { revert(add(resultData, 32), mload(resultData)) } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         uint256 toTokenBalance = IERC20Token(toTokenAddress).balanceOf(address(this)); | ||||
|         // Transfer the converted `toToken`s to `to`. | ||||
|         LibERC20Token.transfer(toTokenAddress, to, toTokenBalance); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             data.fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             toTokenBalance, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Magic success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
| @@ -38,10 +38,11 @@ contract UniswapBridge is | ||||
| { | ||||
|     // Struct to hold `bridgeTransferFrom()` local variables in memory and to avoid | ||||
|     // stack overflows. | ||||
|     struct WithdrawToState { | ||||
|     struct TransferState { | ||||
|         IUniswapExchange exchange; | ||||
|         uint256 fromTokenBalance; | ||||
|         IEtherToken weth; | ||||
|         uint256 boughtAmount; | ||||
|     } | ||||
|  | ||||
|     // solhint-disable no-empty-blocks | ||||
| @@ -55,13 +56,14 @@ contract UniswapBridge is | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` | ||||
|     ///      token encoded in the bridge data. | ||||
|     /// @param toTokenAddress The token to buy and transfer to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded "from" token address. | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address /* from */, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
| @@ -70,7 +72,7 @@ contract UniswapBridge is | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // State memory object to avoid stack overflows. | ||||
|         WithdrawToState memory state; | ||||
|         TransferState memory state; | ||||
|         // Decode the bridge data to get the `fromTokenAddress`. | ||||
|         (address fromTokenAddress) = abi.decode(bridgeData, (address)); | ||||
|  | ||||
| @@ -96,7 +98,7 @@ contract UniswapBridge is | ||||
|             state.weth.withdraw(state.fromTokenBalance); | ||||
|             // Buy as much of `toTokenAddress` token with ETH as possible and | ||||
|             // transfer it to `to`. | ||||
|             state.exchange.ethToTokenTransferInput.value(state.fromTokenBalance)( | ||||
|             state.boughtAmount = state.exchange.ethToTokenTransferInput.value(state.fromTokenBalance)( | ||||
|                 // Minimum buy amount. | ||||
|                 amount, | ||||
|                 // Expires after this block. | ||||
| @@ -108,9 +110,9 @@ contract UniswapBridge is | ||||
|         // Convert from a token to WETH. | ||||
|         } else if (toTokenAddress == address(state.weth)) { | ||||
|             // Grant the exchange an allowance. | ||||
|             _grantExchangeAllowance(state.exchange, fromTokenAddress); | ||||
|             _grantExchangeAllowance(state.exchange, fromTokenAddress, state.fromTokenBalance); | ||||
|             // Buy as much ETH with `fromTokenAddress` token as possible. | ||||
|             uint256 ethBought = state.exchange.tokenToEthSwapInput( | ||||
|             state.boughtAmount = state.exchange.tokenToEthSwapInput( | ||||
|                 // Sell all tokens we hold. | ||||
|                 state.fromTokenBalance, | ||||
|                 // Minimum buy amount. | ||||
| @@ -119,17 +121,17 @@ contract UniswapBridge is | ||||
|                 block.timestamp | ||||
|             ); | ||||
|             // Wrap the ETH. | ||||
|             state.weth.deposit.value(ethBought)(); | ||||
|             state.weth.deposit.value(state.boughtAmount)(); | ||||
|             // Transfer the WETH to `to`. | ||||
|             IEtherToken(toTokenAddress).transfer(to, ethBought); | ||||
|             IEtherToken(toTokenAddress).transfer(to, state.boughtAmount); | ||||
|  | ||||
|         // Convert from one token to another. | ||||
|         } else { | ||||
|             // Grant the exchange an allowance. | ||||
|             _grantExchangeAllowance(state.exchange, fromTokenAddress); | ||||
|             _grantExchangeAllowance(state.exchange, fromTokenAddress, state.fromTokenBalance); | ||||
|             // Buy as much `toTokenAddress` token with `fromTokenAddress` token | ||||
|             // and transfer it to `to`. | ||||
|             state.exchange.tokenToTokenTransferInput( | ||||
|             state.boughtAmount = state.exchange.tokenToTokenTransferInput( | ||||
|                 // Sell all tokens we hold. | ||||
|                 state.fromTokenBalance, | ||||
|                 // Minimum buy amount. | ||||
| @@ -144,6 +146,15 @@ contract UniswapBridge is | ||||
|                 toTokenAddress | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             fromTokenAddress, | ||||
|             toTokenAddress, | ||||
|             state.fromTokenBalance, | ||||
|             state.boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
| @@ -165,10 +176,19 @@ contract UniswapBridge is | ||||
|     ///      on behalf of this contract. | ||||
|     /// @param exchange The Uniswap token exchange. | ||||
|     /// @param tokenAddress The token address for the exchange. | ||||
|     function _grantExchangeAllowance(IUniswapExchange exchange, address tokenAddress) | ||||
|     /// @param minimumAllowance The minimum necessary allowance. | ||||
|     function _grantExchangeAllowance( | ||||
|         IUniswapExchange exchange, | ||||
|         address tokenAddress, | ||||
|         uint256 minimumAllowance | ||||
|     ) | ||||
|         private | ||||
|     { | ||||
|         LibERC20Token.approve(tokenAddress, address(exchange), uint256(-1)); | ||||
|         LibERC20Token.approveIfBelow( | ||||
|             tokenAddress, | ||||
|             address(exchange), | ||||
|             minimumAllowance | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Retrieves the uniswap exchange for a given token pair. | ||||
|   | ||||
							
								
								
									
										135
									
								
								contracts/asset-proxy/contracts/src/bridges/UniswapV2Bridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								contracts/asset-proxy/contracts/src/bridges/UniswapV2Bridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibAddressArray.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IUniswapV2Router01.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
|  | ||||
|  | ||||
| // solhint-disable space-after-comma | ||||
| // solhint-disable not-rely-on-time | ||||
| contract UniswapV2Bridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     struct TransferState { | ||||
|         address[] path; | ||||
|         uint256 fromTokenBalance; | ||||
|     } | ||||
|  | ||||
|     /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` | ||||
|     ///      token encoded in the bridge data. | ||||
|     /// @param toTokenAddress The token to buy and transfer to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded path of token addresses. Last element must be toTokenAddress | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // hold variables to get around stack depth limitations | ||||
|         TransferState memory state; | ||||
|  | ||||
|         // Decode the bridge data to get the `fromTokenAddress`. | ||||
|         // solhint-disable indent | ||||
|         state.path = abi.decode(bridgeData, (address[])); | ||||
|         // solhint-enable indent | ||||
|  | ||||
|         require(state.path.length >= 2, "UniswapV2Bridge/PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | ||||
|         require(state.path[state.path.length - 1] == toTokenAddress, "UniswapV2Bridge/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"); | ||||
|  | ||||
|         // Just transfer the tokens if they're the same. | ||||
|         if (state.path[0] == toTokenAddress) { | ||||
|             LibERC20Token.transfer(state.path[0], to, amount); | ||||
|             return BRIDGE_SUCCESS; | ||||
|         } | ||||
|  | ||||
|         // Get our balance of `fromTokenAddress` token. | ||||
|         state.fromTokenBalance = IERC20Token(state.path[0]).balanceOf(address(this)); | ||||
|  | ||||
|         // Grant the Uniswap router an allowance. | ||||
|         LibERC20Token.approveIfBelow( | ||||
|             state.path[0], | ||||
|             _getUniswapV2Router01Address(), | ||||
|             state.fromTokenBalance | ||||
|         ); | ||||
|  | ||||
|         // Buy as much `toTokenAddress` token with `fromTokenAddress` token | ||||
|         // and transfer it to `to`. | ||||
|         IUniswapV2Router01 router = IUniswapV2Router01(_getUniswapV2Router01Address()); | ||||
|         uint[] memory amounts = router.swapExactTokensForTokens( | ||||
|              // Sell all tokens we hold. | ||||
|             state.fromTokenBalance, | ||||
|              // Minimum buy amount. | ||||
|             amount, | ||||
|             // Convert `fromTokenAddress` to `toTokenAddress`. | ||||
|             state.path, | ||||
|             // Recipient is `to`. | ||||
|             to, | ||||
|             // Expires after this block. | ||||
|             block.timestamp | ||||
|         ); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             // input token | ||||
|             state.path[0], | ||||
|             // output token | ||||
|             toTokenAddress, | ||||
|             // input token amount | ||||
|             state.fromTokenBalance, | ||||
|             // output token amount | ||||
|             amounts[amounts.length - 1], | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|  | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,39 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
|  | ||||
|  | ||||
| interface IBalancerPool { | ||||
|     /// @dev Sell `tokenAmountIn` of `tokenIn` and receive `tokenOut`. | ||||
|     /// @param tokenIn The token being sold | ||||
|     /// @param tokenAmountIn The amount of `tokenIn` to sell. | ||||
|     /// @param tokenOut The token being bought. | ||||
|     /// @param minAmountOut The minimum amount of `tokenOut` to buy. | ||||
|     /// @param maxPrice The maximum value for `spotPriceAfter`. | ||||
|     /// @return tokenAmountOut The amount of `tokenOut` bought. | ||||
|     /// @return spotPriceAfter The new marginal spot price of the given | ||||
|     ///         token pair for this pool. | ||||
|     function swapExactAmountIn( | ||||
|         address tokenIn, | ||||
|         uint tokenAmountIn, | ||||
|         address tokenOut, | ||||
|         uint minAmountOut, | ||||
|         uint maxPrice | ||||
|     ) external returns (uint tokenAmountOut, uint spotPriceAfter); | ||||
| } | ||||
| @@ -0,0 +1,38 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
|  | ||||
|  | ||||
| contract IContractRegistry { | ||||
|     function addressOf( | ||||
|         bytes32 contractName | ||||
|     ) external returns(address); | ||||
| } | ||||
|  | ||||
|  | ||||
| contract IBancorNetwork { | ||||
|     function convertByPath( | ||||
|         address[] calldata _path, | ||||
|         uint256 _amount, | ||||
|         uint256 _minReturn, | ||||
|         address _beneficiary, | ||||
|         address _affiliateAccount, | ||||
|         uint256 _affiliateFee | ||||
|     ) external payable returns (uint256); | ||||
| } | ||||
| @@ -22,22 +22,6 @@ pragma solidity ^0.5.9; | ||||
| // solhint-disable func-name-mixedcase | ||||
| interface ICurve { | ||||
|  | ||||
|     /// @dev Sell `sellAmount` of `fromToken` token and receive `toToken` token. | ||||
|     ///      This function exists on early versions of Curve (USDC/DAI) | ||||
|     /// @param i The token index being sold. | ||||
|     /// @param j The token index being bought. | ||||
|     /// @param sellAmount The amount of token being bought. | ||||
|     /// @param minBuyAmount The minimum buy amount of the token being bought. | ||||
|     /// @param deadline The time in seconds when this operation should expire. | ||||
|     function exchange_underlying( | ||||
|         int128 i, | ||||
|         int128 j, | ||||
|         uint256 sellAmount, | ||||
|         uint256 minBuyAmount, | ||||
|         uint256 deadline | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     /// @dev Sell `sellAmount` of `fromToken` token and receive `toToken` token. | ||||
|     ///      This function exists on later versions of Curve (USDC/DAI/USDT) | ||||
|     /// @param i The token index being sold. | ||||
| @@ -65,7 +49,6 @@ interface ICurve { | ||||
|         returns (uint256 dy); | ||||
|  | ||||
|     /// @dev Get the amount of `fromToken` by buying `buyAmount` of `toToken` | ||||
|     ///      This function exists on later versions of Curve (USDC/DAI/USDT) | ||||
|     /// @param i The token index being sold. | ||||
|     /// @param j The token index being bought. | ||||
|     /// @param buyAmount The amount of token being bought. | ||||
|   | ||||
| @@ -21,9 +21,25 @@ pragma solidity ^0.5.9; | ||||
|  | ||||
| contract IERC20Bridge { | ||||
|  | ||||
|     // @dev Result of a successful bridge call. | ||||
|     /// @dev Result of a successful bridge call. | ||||
|     bytes4 constant internal BRIDGE_SUCCESS = 0xdc1600f3; | ||||
|  | ||||
|     /// @dev Emitted when a trade occurs. | ||||
|     /// @param inputToken The token the bridge is converting from. | ||||
|     /// @param outputToken The token the bridge is converting to. | ||||
|     /// @param inputTokenAmount Amount of input token. | ||||
|     /// @param outputTokenAmount Amount of output token. | ||||
|     /// @param from The `from` address in `bridgeTransferFrom()` | ||||
|     /// @param to The `to` address in `bridgeTransferFrom()` | ||||
|     event ERC20BridgeTransfer( | ||||
|         address inputToken, | ||||
|         address outputToken, | ||||
|         uint256 inputTokenAmount, | ||||
|         uint256 outputTokenAmount, | ||||
|         address from, | ||||
|         address to | ||||
|     ); | ||||
|  | ||||
|     /// @dev Transfers `amount` of the ERC20 `tokenAddress` from `from` to `to`. | ||||
|     /// @param tokenAddress The address of the ERC20 token to transfer. | ||||
|     /// @param from Address to transfer asset from. | ||||
|   | ||||
							
								
								
									
										40
									
								
								contracts/asset-proxy/contracts/src/interfaces/IGasToken.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								contracts/asset-proxy/contracts/src/interfaces/IGasToken.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -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.15; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
|  | ||||
|  | ||||
| contract IGasToken is IERC20Token { | ||||
|  | ||||
|     /// @dev Frees up to `value` sub-tokens | ||||
|     /// @param value The amount of tokens to free | ||||
|     /// @return How many tokens were freed | ||||
|     function freeUpTo(uint256 value) external returns (uint256 freed); | ||||
|  | ||||
|     /// @dev Frees up to `value` sub-tokens owned by `from` | ||||
|     /// @param from The owner of tokens to spend | ||||
|     /// @param value The amount of tokens to free | ||||
|     /// @return How many tokens were freed | ||||
|     function freeFromUpTo(address from, uint256 value) external returns (uint256 freed); | ||||
|  | ||||
|     /// @dev Mints `value` amount of tokens | ||||
|     /// @param value The amount of tokens to mint | ||||
|     function mint(uint256 value) external; | ||||
| } | ||||
| @@ -42,5 +42,31 @@ interface IKyberNetworkProxy { | ||||
|     ) | ||||
|         external | ||||
|         payable | ||||
|         returns(uint256 boughtAmount); | ||||
|         returns (uint256 boughtAmount); | ||||
|  | ||||
|     /// @dev Sells `sellTokenAddress` tokens for `buyTokenAddress` tokens | ||||
|     /// using a hint for the reserve. | ||||
|     /// @param sellTokenAddress Token to sell. | ||||
|     /// @param sellAmount Amount of tokens to sell. | ||||
|     /// @param buyTokenAddress Token to buy. | ||||
|     /// @param recipientAddress Address to send bought tokens to. | ||||
|     /// @param maxBuyTokenAmount A limit on the amount of tokens to buy. | ||||
|     /// @param minConversionRate The minimal conversion rate. If actual rate | ||||
|     ///        is lower, trade is canceled. | ||||
|     /// @param walletId The wallet ID to send part of the fees | ||||
|     /// @param hint The hint for the selective inclusion (or exclusion) of reserves | ||||
|     /// @return boughtAmount Amount of tokens bought. | ||||
|     function tradeWithHint( | ||||
|         address sellTokenAddress, | ||||
|         uint256 sellAmount, | ||||
|         address buyTokenAddress, | ||||
|         address payable recipientAddress, | ||||
|         uint256 maxBuyTokenAmount, | ||||
|         uint256 minConversionRate, | ||||
|         address payable walletId, | ||||
|         bytes calldata hint | ||||
|     ) | ||||
|         external | ||||
|         payable | ||||
|         returns (uint256 boughtAmount); | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* | ||||
| 
 | ||||
|   Copyright 2019 ZeroEx Intl. | ||||
|   Copyright 2020 ZeroEx Intl. | ||||
| 
 | ||||
|   Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|   you may not use this file except in compliance with the License. | ||||
| @@ -19,14 +19,14 @@ | ||||
| pragma solidity ^0.5.9; | ||||
| 
 | ||||
| 
 | ||||
| interface IKyberNetwork { | ||||
| interface IMStable { | ||||
| 
 | ||||
|     function getExpectedRate( | ||||
|         address fromToken, | ||||
|         address toToken, | ||||
|         uint256 fromAmount | ||||
|     function swap( | ||||
|         address _input, | ||||
|         address _output, | ||||
|         uint256 _quantity, | ||||
|         address _recipient | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256 expectedRate, uint256 slippageRate); | ||||
|         returns (uint256 output); | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* | ||||
| 
 | ||||
|   Copyright 2019 ZeroEx Intl. | ||||
|   Copyright 2020 ZeroEx Intl. | ||||
| 
 | ||||
|   Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|   you may not use this file except in compliance with the License. | ||||
| @@ -19,18 +19,22 @@ | ||||
| pragma solidity ^0.5.9; | ||||
| 
 | ||||
| 
 | ||||
| interface ILiquidityProviderRegistry { | ||||
| interface IMooniswapRegistry { | ||||
| 
 | ||||
|     /// @dev Returns the address of a liquidity provider for the given market | ||||
|     ///      (takerToken, makerToken), reverting if the pool does not exist. | ||||
|     /// @param takerToken Taker asset managed by liquidity provider. | ||||
|     /// @param makerToken Maker asset managed by liquidity provider. | ||||
|     /// @return Address of the liquidity provider. | ||||
|     function getLiquidityProviderForMarket( | ||||
|         address takerToken, | ||||
|         address makerToken | ||||
|     function pools(address token1, address token2) external view returns(address); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| interface IMooniswap { | ||||
| 
 | ||||
|     function swap( | ||||
|         address fromToken, | ||||
|         address destToken, | ||||
|         uint256 amount, | ||||
|         uint256 minReturn, | ||||
|         address referral | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (address providerAddress); | ||||
|         payable | ||||
|         returns(uint256 returnAmount); | ||||
| } | ||||
							
								
								
									
										34
									
								
								contracts/asset-proxy/contracts/src/interfaces/IShell.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								contracts/asset-proxy/contracts/src/interfaces/IShell.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
|  | ||||
|  | ||||
| interface IShell { | ||||
|  | ||||
|     function originSwap( | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 fromAmount, | ||||
|         uint256 minTargetAmount, | ||||
|         uint256 deadline | ||||
|     ) | ||||
|         external | ||||
|         returns (uint256 toAmount); | ||||
| } | ||||
|  | ||||
| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
|  | ||||
|  | ||||
| interface IUniswapV2Router01 { | ||||
|  | ||||
|     /// @dev Swaps an exact amount of input tokens for as many output tokens as possible, along the route determined by the path. | ||||
|     ///      The first element of path is the input token, the last is the output token, and any intermediate elements represent | ||||
|     ///      intermediate pairs to trade through (if, for example, a direct pair does not exist). | ||||
|     /// @param amountIn The amount of input tokens to send. | ||||
|     /// @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert. | ||||
|     /// @param path An array of token addresses. path.length must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. | ||||
|     /// @param to Recipient of the output tokens. | ||||
|     /// @param deadline Unix timestamp after which the transaction will revert. | ||||
|     /// @return amounts The input token amount and all subsequent output token amounts. | ||||
|     function swapExactTokensForTokens( | ||||
|         uint amountIn, | ||||
|         uint amountOutMin, | ||||
|         address[] calldata path, | ||||
|         address to, | ||||
|         uint deadline | ||||
|     ) external returns (uint[] memory amounts); | ||||
| } | ||||
							
								
								
									
										247
									
								
								contracts/asset-proxy/contracts/test/TestBancorBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								contracts/asset-proxy/contracts/test/TestBancorBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,247 @@ | ||||
| /* | ||||
|  | ||||
|   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.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibAddressArray.sol"; | ||||
| import "../src/bridges/BancorBridge.sol"; | ||||
| import "../src/interfaces/IBancorNetwork.sol"; | ||||
|  | ||||
|  | ||||
| contract TestEventsRaiser { | ||||
|  | ||||
|     event TokenTransfer( | ||||
|         address token, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ); | ||||
|  | ||||
|     event TokenApprove( | ||||
|         address spender, | ||||
|         uint256 allowance | ||||
|     ); | ||||
|  | ||||
|     event ConvertByPathInput( | ||||
|         uint amountIn, | ||||
|         uint amountOutMin, | ||||
|         address toTokenAddress, | ||||
|         address to, | ||||
|         address feeRecipient, | ||||
|         uint256 feeAmount | ||||
|     ); | ||||
|  | ||||
|     function raiseTokenTransfer( | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         external | ||||
|     { | ||||
|         emit TokenTransfer( | ||||
|             msg.sender, | ||||
|             from, | ||||
|             to, | ||||
|             amount | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function raiseTokenApprove(address spender, uint256 allowance) external { | ||||
|         emit TokenApprove(spender, allowance); | ||||
|     } | ||||
|  | ||||
|     function raiseConvertByPathInput( | ||||
|         uint amountIn, | ||||
|         uint amountOutMin, | ||||
|         address toTokenAddress, | ||||
|         address to, | ||||
|         address feeRecipient, | ||||
|         uint256 feeAmount | ||||
|     ) external | ||||
|     { | ||||
|         emit ConvertByPathInput( | ||||
|             amountIn, | ||||
|             amountOutMin, | ||||
|             toTokenAddress, | ||||
|             to, | ||||
|             feeRecipient, | ||||
|             feeAmount | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /// @dev A minimalist ERC20 token. | ||||
| contract TestToken { | ||||
|  | ||||
|     using LibSafeMath for uint256; | ||||
|  | ||||
|     mapping (address => uint256) public balances; | ||||
|     string private _nextRevertReason; | ||||
|  | ||||
|     /// @dev Set the balance for `owner`. | ||||
|     function setBalance(address owner, uint256 balance) | ||||
|         external | ||||
|         payable | ||||
|     { | ||||
|         balances[owner] = balance; | ||||
|     } | ||||
|  | ||||
|     /// @dev Just emits a TokenTransfer event on the caller | ||||
|     function transfer(address to, uint256 amount) | ||||
|         external | ||||
|         returns (bool) | ||||
|     { | ||||
|         TestEventsRaiser(msg.sender).raiseTokenTransfer(msg.sender, to, amount); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /// @dev Just emits a TokenApprove event on the caller | ||||
|     function approve(address spender, uint256 allowance) | ||||
|         external | ||||
|         returns (bool) | ||||
|     { | ||||
|         TestEventsRaiser(msg.sender).raiseTokenApprove(spender, allowance); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     function allowance(address, address) external view returns (uint256) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /// @dev Retrieve the balance for `owner`. | ||||
|     function balanceOf(address owner) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256) | ||||
|     { | ||||
|         return balances[owner]; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /// @dev Mock the BancorNetwork contract | ||||
| contract TestBancorNetwork is | ||||
|     IBancorNetwork | ||||
| { | ||||
|     string private _nextRevertReason; | ||||
|  | ||||
|     /// @dev Set the revert reason for `swapExactTokensForTokens`. | ||||
|     function setRevertReason(string calldata reason) | ||||
|         external | ||||
|     { | ||||
|         _nextRevertReason = reason; | ||||
|     } | ||||
|  | ||||
|     function convertByPath( | ||||
|         address[] calldata _path, | ||||
|         uint256 _amount, | ||||
|         uint256 _minReturn, | ||||
|         address _beneficiary, | ||||
|         address _affiliateAccount, | ||||
|         uint256 _affiliateFee | ||||
|     ) external payable returns (uint256) | ||||
|     { | ||||
|         _revertIfReasonExists(); | ||||
|  | ||||
|         TestEventsRaiser(msg.sender).raiseConvertByPathInput( | ||||
|             // tokens sold | ||||
|             _amount, | ||||
|             // tokens bought | ||||
|             _minReturn, | ||||
|             // output token | ||||
|             _path[_path.length - 1], | ||||
|             // recipient | ||||
|             _beneficiary, | ||||
|             // fee recipient | ||||
|             _affiliateAccount, | ||||
|             // fee amount | ||||
|             _affiliateFee | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function _revertIfReasonExists() | ||||
|         private | ||||
|         view | ||||
|     { | ||||
|         if (bytes(_nextRevertReason).length != 0) { | ||||
|             revert(_nextRevertReason); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| /// @dev BancorBridge overridden to mock tokens and BancorNetwork | ||||
| contract TestBancorBridge is | ||||
|     BancorBridge, | ||||
|     TestEventsRaiser | ||||
| { | ||||
|  | ||||
|     // Token address to TestToken instance. | ||||
|     mapping (address => TestToken) private _testTokens; | ||||
|     // TestRouter instance. | ||||
|     TestBancorNetwork private _testNetwork; | ||||
|  | ||||
|     constructor() public { | ||||
|         _testNetwork = new TestBancorNetwork(); | ||||
|     } | ||||
|  | ||||
|     function setNetworkRevertReason(string calldata revertReason) | ||||
|         external | ||||
|     { | ||||
|         _testNetwork.setRevertReason(revertReason); | ||||
|     } | ||||
|  | ||||
|     /// @dev Sets the balance of this contract for an existing token. | ||||
|     function setTokenBalance(address tokenAddress, uint256 balance) | ||||
|         external | ||||
|     { | ||||
|         TestToken token = _testTokens[tokenAddress]; | ||||
|         token.setBalance(address(this), balance); | ||||
|     } | ||||
|  | ||||
|     /// @dev Create a new token | ||||
|     /// @param tokenAddress The token address. If zero, one will be created. | ||||
|     function createToken( | ||||
|         address tokenAddress | ||||
|     ) | ||||
|         external | ||||
|         returns (TestToken token) | ||||
|     { | ||||
|         token = TestToken(tokenAddress); | ||||
|         if (tokenAddress == address(0)) { | ||||
|             token = new TestToken(); | ||||
|         } | ||||
|         _testTokens[address(token)] = token; | ||||
|  | ||||
|         return token; | ||||
|     } | ||||
|  | ||||
|     function getNetworkAddress() | ||||
|         external | ||||
|         view | ||||
|         returns (address) | ||||
|     { | ||||
|         return address(_testNetwork); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										244
									
								
								contracts/asset-proxy/contracts/test/TestDexForwarderBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								contracts/asset-proxy/contracts/test/TestDexForwarderBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "../src/bridges/DexForwarderBridge.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; | ||||
|  | ||||
|  | ||||
| interface ITestDexForwarderBridge { | ||||
|     event BridgeTransferFromCalled( | ||||
|         address caller, | ||||
|         uint256 inputTokenBalance, | ||||
|         address inputToken, | ||||
|         address outputToken, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ); | ||||
|  | ||||
|     event TokenTransferCalled( | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ); | ||||
|  | ||||
|     function emitBridgeTransferFromCalled( | ||||
|         address caller, | ||||
|         uint256 inputTokenBalance, | ||||
|         address inputToken, | ||||
|         address outputToken, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) external; | ||||
|  | ||||
|     function emitTokenTransferCalled( | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) external; | ||||
| } | ||||
|  | ||||
|  | ||||
| interface ITestDexForwarderBridgeTestToken { | ||||
|  | ||||
|     function transfer(address to, uint256 amount) | ||||
|         external | ||||
|         returns (bool); | ||||
|  | ||||
|     function mint(address to, uint256 amount) | ||||
|         external; | ||||
|  | ||||
|     function balanceOf(address owner) external view returns (uint256); | ||||
| } | ||||
|  | ||||
|  | ||||
| contract TestDexForwarderBridgeTestBridge { | ||||
|  | ||||
|     bytes4 private _returnCode; | ||||
|     string private _revertError; | ||||
|     uint256 private _transferAmount; | ||||
|     ITestDexForwarderBridge private _testContract; | ||||
|  | ||||
|     constructor(bytes4 returnCode, string memory revertError) public { | ||||
|         _testContract = ITestDexForwarderBridge(msg.sender); | ||||
|         _returnCode = returnCode; | ||||
|         _revertError = revertError; | ||||
|     } | ||||
|  | ||||
|     function setTransferAmount(uint256 amount) external { | ||||
|         _transferAmount = amount; | ||||
|     } | ||||
|  | ||||
|     function bridgeTransferFrom( | ||||
|         address outputToken, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes memory bridgeData | ||||
|     ) | ||||
|         public | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         if (bytes(_revertError).length != 0) { | ||||
|             revert(_revertError); | ||||
|         } | ||||
|         address inputToken = abi.decode(bridgeData, (address)); | ||||
|         _testContract.emitBridgeTransferFromCalled( | ||||
|             msg.sender, | ||||
|             ITestDexForwarderBridgeTestToken(inputToken).balanceOf(address(this)), | ||||
|             inputToken, | ||||
|             outputToken, | ||||
|             from, | ||||
|             to, | ||||
|             amount | ||||
|         ); | ||||
|         ITestDexForwarderBridgeTestToken(outputToken).mint(to, _transferAmount); | ||||
|         return _returnCode; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| contract TestDexForwarderBridgeTestToken { | ||||
|  | ||||
|     using LibSafeMath for uint256; | ||||
|  | ||||
|     mapping(address => uint256) public balanceOf; | ||||
|     ITestDexForwarderBridge private _testContract; | ||||
|  | ||||
|     constructor() public { | ||||
|         _testContract = ITestDexForwarderBridge(msg.sender); | ||||
|     } | ||||
|  | ||||
|     function transfer(address to, uint256 amount) | ||||
|         external | ||||
|         returns (bool) | ||||
|     { | ||||
|         balanceOf[msg.sender] = balanceOf[msg.sender].safeSub(amount); | ||||
|         balanceOf[to] = balanceOf[to].safeAdd(amount); | ||||
|         _testContract.emitTokenTransferCalled(msg.sender, to, amount); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     function mint(address owner, uint256 amount) | ||||
|         external | ||||
|     { | ||||
|         balanceOf[owner] = balanceOf[owner].safeAdd(amount); | ||||
|     } | ||||
|  | ||||
|     function setBalance(address owner, uint256 amount) | ||||
|         external | ||||
|     { | ||||
|         balanceOf[owner] = amount; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| contract TestDexForwarderBridge is | ||||
|     ITestDexForwarderBridge, | ||||
|     DexForwarderBridge | ||||
| { | ||||
|     address private AUTHORIZED_ADDRESS; // solhint-disable-line var-name-mixedcase | ||||
|  | ||||
|     function setAuthorized(address authorized) | ||||
|         public | ||||
|     { | ||||
|         AUTHORIZED_ADDRESS = authorized; | ||||
|     } | ||||
|  | ||||
|     function createBridge( | ||||
|         bytes4 returnCode, | ||||
|         string memory revertError | ||||
|     ) | ||||
|         public | ||||
|         returns (address bridge) | ||||
|     { | ||||
|         return address(new TestDexForwarderBridgeTestBridge(returnCode, revertError)); | ||||
|     } | ||||
|  | ||||
|     function createToken() public returns (address token) { | ||||
|         return address(new TestDexForwarderBridgeTestToken()); | ||||
|     } | ||||
|  | ||||
|     function setTokenBalance(address token, address owner, uint256 amount) public { | ||||
|         TestDexForwarderBridgeTestToken(token).setBalance(owner, amount); | ||||
|     } | ||||
|  | ||||
|     function setBridgeTransferAmount(address bridge, uint256 amount) public { | ||||
|         TestDexForwarderBridgeTestBridge(bridge).setTransferAmount(amount); | ||||
|     } | ||||
|  | ||||
|     function emitBridgeTransferFromCalled( | ||||
|         address caller, | ||||
|         uint256 inputTokenBalance, | ||||
|         address inputToken, | ||||
|         address outputToken, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         public | ||||
|     { | ||||
|         emit BridgeTransferFromCalled( | ||||
|             caller, | ||||
|             inputTokenBalance, | ||||
|             inputToken, | ||||
|             outputToken, | ||||
|             from, | ||||
|             to, | ||||
|             amount | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function emitTokenTransferCalled( | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         public | ||||
|     { | ||||
|         emit TokenTransferCalled( | ||||
|             from, | ||||
|             to, | ||||
|             amount | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function balanceOf(address token, address owner) public view returns (uint256) { | ||||
|         return TestDexForwarderBridgeTestToken(token).balanceOf(owner); | ||||
|     } | ||||
|  | ||||
|     function _getGstAddress() | ||||
|         internal | ||||
|         view | ||||
|         returns (address gst) | ||||
|     { | ||||
|         return address(0); | ||||
|     } | ||||
|  | ||||
|     function _getERC20BridgeProxyAddress() | ||||
|         internal | ||||
|         view | ||||
|         returns (address erc20BridgeProxyAddress) | ||||
|     { | ||||
|         return AUTHORIZED_ADDRESS; | ||||
|     } | ||||
| } | ||||
| @@ -110,6 +110,10 @@ contract TestToken { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     function allowance(address, address) external view returns (uint256) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /// @dev Retrieve the balance for `owner`. | ||||
|     function balanceOf(address owner) | ||||
|         external | ||||
|   | ||||
| @@ -110,6 +110,10 @@ contract TestToken { | ||||
|         return _testContract.wethDeposit.value(msg.value)(msg.sender); | ||||
|     } | ||||
|  | ||||
|     function allowance(address, address) external view returns (uint256) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     function balanceOf(address owner) | ||||
|         external | ||||
|         view | ||||
| @@ -197,6 +201,33 @@ contract TestKyberBridge is | ||||
|         return _nextFillAmount; | ||||
|     } | ||||
|  | ||||
|     function tradeWithHint( | ||||
|         address sellTokenAddress, | ||||
|         uint256 sellAmount, | ||||
|         address buyTokenAddress, | ||||
|         address payable recipientAddress, | ||||
|         uint256 maxBuyTokenAmount, | ||||
|         uint256 minConversionRate, | ||||
|         address payable walletId, | ||||
|         bytes calldata hint | ||||
|     ) | ||||
|         external | ||||
|         payable | ||||
|         returns (uint256 boughtAmount) | ||||
|     { | ||||
|         emit KyberBridgeTrade( | ||||
|             msg.value, | ||||
|             sellTokenAddress, | ||||
|             sellAmount, | ||||
|             buyTokenAddress, | ||||
|             recipientAddress, | ||||
|             maxBuyTokenAmount, | ||||
|             minConversionRate, | ||||
|             walletId | ||||
|         ); | ||||
|         return _nextFillAmount; | ||||
|     } | ||||
|  | ||||
|     function createToken(uint8 decimals) | ||||
|         external | ||||
|         returns (address tokenAddress) | ||||
|   | ||||
| @@ -224,6 +224,10 @@ contract TestToken { | ||||
|         TestEventsRaiser(msg.sender).raiseWethWithdraw(amount); | ||||
|     } | ||||
|  | ||||
|     function allowance(address, address) external view returns (uint256) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /// @dev Retrieve the balance for `owner`. | ||||
|     function balanceOf(address owner) | ||||
|         external | ||||
|   | ||||
							
								
								
									
										253
									
								
								contracts/asset-proxy/contracts/test/TestUniswapV2Bridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								contracts/asset-proxy/contracts/test/TestUniswapV2Bridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,253 @@ | ||||
| /* | ||||
|  | ||||
|   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.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibAddressArray.sol"; | ||||
| import "../src/bridges/UniswapV2Bridge.sol"; | ||||
| import "../src/interfaces/IUniswapV2Router01.sol"; | ||||
|  | ||||
|  | ||||
| contract TestEventsRaiser { | ||||
|  | ||||
|     event TokenTransfer( | ||||
|         address token, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ); | ||||
|  | ||||
|     event TokenApprove( | ||||
|         address spender, | ||||
|         uint256 allowance | ||||
|     ); | ||||
|  | ||||
|     event SwapExactTokensForTokensInput( | ||||
|         uint amountIn, | ||||
|         uint amountOutMin, | ||||
|         address toTokenAddress, | ||||
|         address to, | ||||
|         uint deadline | ||||
|     ); | ||||
|  | ||||
|     function raiseTokenTransfer( | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         external | ||||
|     { | ||||
|         emit TokenTransfer( | ||||
|             msg.sender, | ||||
|             from, | ||||
|             to, | ||||
|             amount | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function raiseTokenApprove(address spender, uint256 allowance) external { | ||||
|         emit TokenApprove(spender, allowance); | ||||
|     } | ||||
|  | ||||
|     function raiseSwapExactTokensForTokensInput( | ||||
|         uint amountIn, | ||||
|         uint amountOutMin, | ||||
|         address toTokenAddress, | ||||
|         address to, | ||||
|         uint deadline | ||||
|     ) external | ||||
|     { | ||||
|         emit SwapExactTokensForTokensInput( | ||||
|             amountIn, | ||||
|             amountOutMin, | ||||
|             toTokenAddress, | ||||
|             to, | ||||
|             deadline | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /// @dev A minimalist ERC20 token. | ||||
| contract TestToken { | ||||
|  | ||||
|     using LibSafeMath for uint256; | ||||
|  | ||||
|     mapping (address => uint256) public balances; | ||||
|     string private _nextRevertReason; | ||||
|  | ||||
|     /// @dev Set the balance for `owner`. | ||||
|     function setBalance(address owner, uint256 balance) | ||||
|         external | ||||
|         payable | ||||
|     { | ||||
|         balances[owner] = balance; | ||||
|     } | ||||
|  | ||||
|     /// @dev Just emits a TokenTransfer event on the caller | ||||
|     function transfer(address to, uint256 amount) | ||||
|         external | ||||
|         returns (bool) | ||||
|     { | ||||
|         TestEventsRaiser(msg.sender).raiseTokenTransfer(msg.sender, to, amount); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /// @dev Just emits a TokenApprove event on the caller | ||||
|     function approve(address spender, uint256 allowance) | ||||
|         external | ||||
|         returns (bool) | ||||
|     { | ||||
|         TestEventsRaiser(msg.sender).raiseTokenApprove(spender, allowance); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     function allowance(address, address) external view returns (uint256) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /// @dev Retrieve the balance for `owner`. | ||||
|     function balanceOf(address owner) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256) | ||||
|     { | ||||
|         return balances[owner]; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /// @dev Mock the UniswapV2Router01 contract | ||||
| contract TestRouter is | ||||
|     IUniswapV2Router01 | ||||
| { | ||||
|     string private _nextRevertReason; | ||||
|  | ||||
|     /// @dev Set the revert reason for `swapExactTokensForTokens`. | ||||
|     function setRevertReason(string calldata reason) | ||||
|         external | ||||
|     { | ||||
|         _nextRevertReason = reason; | ||||
|     } | ||||
|  | ||||
|     function swapExactTokensForTokens( | ||||
|         uint amountIn, | ||||
|         uint amountOutMin, | ||||
|         address[] calldata path, | ||||
|         address to, | ||||
|         uint deadline | ||||
|     ) external returns (uint[] memory amounts) | ||||
|     { | ||||
|         _revertIfReasonExists(); | ||||
|  | ||||
|         amounts = new uint[](path.length); | ||||
|         amounts[0] = amountIn; | ||||
|         amounts[amounts.length - 1] = amountOutMin; | ||||
|  | ||||
|         TestEventsRaiser(msg.sender).raiseSwapExactTokensForTokensInput( | ||||
|             // tokens sold | ||||
|             amountIn, | ||||
|             // tokens bought | ||||
|             amountOutMin, | ||||
|             // output token (toTokenAddress) | ||||
|             path[path.length - 1], | ||||
|             // recipient | ||||
|             to, | ||||
|             // deadline | ||||
|             deadline | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function _revertIfReasonExists() | ||||
|         private | ||||
|         view | ||||
|     { | ||||
|         if (bytes(_nextRevertReason).length != 0) { | ||||
|             revert(_nextRevertReason); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| /// @dev UniswapV2Bridge overridden to mock tokens and Uniswap router | ||||
| contract TestUniswapV2Bridge is | ||||
|     UniswapV2Bridge, | ||||
|     TestEventsRaiser | ||||
| { | ||||
|  | ||||
|     // Token address to TestToken instance. | ||||
|     mapping (address => TestToken) private _testTokens; | ||||
|     // TestRouter instance. | ||||
|     TestRouter private _testRouter; | ||||
|  | ||||
|     constructor() public { | ||||
|         _testRouter = new TestRouter(); | ||||
|     } | ||||
|  | ||||
|     function setRouterRevertReason(string calldata revertReason) | ||||
|         external | ||||
|     { | ||||
|         _testRouter.setRevertReason(revertReason); | ||||
|     } | ||||
|  | ||||
|     /// @dev Sets the balance of this contract for an existing token. | ||||
|     ///      The wei attached will be the balance. | ||||
|     function setTokenBalance(address tokenAddress, uint256 balance) | ||||
|         external | ||||
|     { | ||||
|         TestToken token = _testTokens[tokenAddress]; | ||||
|         token.setBalance(address(this), balance); | ||||
|     } | ||||
|  | ||||
|     /// @dev Create a new token | ||||
|     /// @param tokenAddress The token address. If zero, one will be created. | ||||
|     function createToken( | ||||
|         address tokenAddress | ||||
|     ) | ||||
|         external | ||||
|         returns (TestToken token) | ||||
|     { | ||||
|         token = TestToken(tokenAddress); | ||||
|         if (tokenAddress == address(0)) { | ||||
|             token = new TestToken(); | ||||
|         } | ||||
|         _testTokens[address(token)] = token; | ||||
|  | ||||
|         return token; | ||||
|     } | ||||
|  | ||||
|     function getRouterAddress() | ||||
|         external | ||||
|         view | ||||
|         returns (address) | ||||
|     { | ||||
|         return address(_testRouter); | ||||
|     } | ||||
|  | ||||
|     function _getUniswapV2Router01Address() | ||||
|         internal | ||||
|         view | ||||
|         returns (address) | ||||
|     { | ||||
|         return address(_testRouter); | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-asset-proxy", | ||||
|     "version": "3.2.5", | ||||
|     "version": "3.7.5", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -38,30 +38,31 @@ | ||||
|         "docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" | ||||
|     }, | ||||
|     "config": { | ||||
|         "abis": "./test/generated-artifacts/@(ChaiBridge|CurveBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestChaiBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json", | ||||
|         "abis": "./test/generated-artifacts/@(BalancerBridge|BancorBridge|ChaiBridge|CreamBridge|CryptoComBridge|CurveBridge|DODOBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IBancorNetwork|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IMooniswap|IShell|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MooniswapBridge|MultiAssetProxy|Ownable|ShellBridge|SnowSwapBridge|StaticCallProxy|SushiSwapBridge|SwerveBridge|TestBancorBridge|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).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" | ||||
|         "url": "https://github.com/0xProject/protocol.git" | ||||
|     }, | ||||
|     "license": "Apache-2.0", | ||||
|     "bugs": { | ||||
|         "url": "https://github.com/0xProject/0x-monorepo/issues" | ||||
|         "url": "https://github.com/0xProject/protocol/issues" | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md", | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.2.2", | ||||
|         "@0x/contracts-gen": "^2.0.8", | ||||
|         "@0x/contracts-test-utils": "^5.3.2", | ||||
|         "@0x/contracts-utils": "^4.4.3", | ||||
|         "@0x/dev-utils": "^3.2.1", | ||||
|         "@0x/sol-compiler": "^4.0.8", | ||||
|         "@0x/ts-doc-gen": "^0.0.22", | ||||
|         "@0x/tslint-config": "^4.0.0", | ||||
|         "@0x/abi-gen": "^5.4.19", | ||||
|         "@0x/contract-wrappers": "^13.12.2", | ||||
|         "@0x/contracts-gen": "^2.0.30", | ||||
|         "@0x/contracts-test-utils": "^5.3.20", | ||||
|         "@0x/contracts-utils": "^4.7.2", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.5.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "@types/node": "12.12.54", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
| @@ -74,24 +75,25 @@ | ||||
|         "solhint": "^1.4.1", | ||||
|         "truffle": "^5.0.32", | ||||
|         "tslint": "5.11.0", | ||||
|         "typedoc": "^0.15.0", | ||||
|         "typedoc": "~0.16.11", | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.1", | ||||
|         "@0x/contracts-erc1155": "^2.1.5", | ||||
|         "@0x/contracts-erc20": "^3.1.5", | ||||
|         "@0x/contracts-erc721": "^3.1.5", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.5", | ||||
|         "@0x/order-utils": "^10.2.4", | ||||
|         "@0x/types": "^3.1.2", | ||||
|         "@0x/typescript-typings": "^5.0.2", | ||||
|         "@0x/utils": "^5.4.1", | ||||
|         "@0x/web3-wrapper": "^7.0.7", | ||||
|         "ethereum-types": "^3.1.0", | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contracts-erc1155": "^2.1.23", | ||||
|         "@0x/contracts-erc20": "^3.3.2", | ||||
|         "@0x/contracts-erc721": "^3.1.23", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.23", | ||||
|         "@0x/order-utils": "^10.4.15", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|     } | ||||
|     }, | ||||
|     "gitHead": "4f91bfd907996b2f4dd383778b50c479c2602b56" | ||||
| } | ||||
|   | ||||
| @@ -5,8 +5,14 @@ | ||||
|  */ | ||||
| import { ContractArtifact } from 'ethereum-types'; | ||||
|  | ||||
| import * as BalancerBridge from '../generated-artifacts/BalancerBridge.json'; | ||||
| import * as BancorBridge from '../generated-artifacts/BancorBridge.json'; | ||||
| import * as ChaiBridge from '../generated-artifacts/ChaiBridge.json'; | ||||
| import * as CreamBridge from '../generated-artifacts/CreamBridge.json'; | ||||
| import * as CryptoComBridge from '../generated-artifacts/CryptoComBridge.json'; | ||||
| import * as CurveBridge from '../generated-artifacts/CurveBridge.json'; | ||||
| import * as DexForwarderBridge from '../generated-artifacts/DexForwarderBridge.json'; | ||||
| import * as DODOBridge from '../generated-artifacts/DODOBridge.json'; | ||||
| import * as DydxBridge from '../generated-artifacts/DydxBridge.json'; | ||||
| import * as ERC1155Proxy from '../generated-artifacts/ERC1155Proxy.json'; | ||||
| import * as ERC20BridgeProxy from '../generated-artifacts/ERC20BridgeProxy.json'; | ||||
| @@ -17,29 +23,47 @@ import * as IAssetData from '../generated-artifacts/IAssetData.json'; | ||||
| import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json'; | ||||
| import * as IAssetProxyDispatcher from '../generated-artifacts/IAssetProxyDispatcher.json'; | ||||
| import * as IAuthorizable from '../generated-artifacts/IAuthorizable.json'; | ||||
| import * as IBalancerPool from '../generated-artifacts/IBalancerPool.json'; | ||||
| import * as IBancorNetwork from '../generated-artifacts/IBancorNetwork.json'; | ||||
| import * as IChai from '../generated-artifacts/IChai.json'; | ||||
| import * as ICurve from '../generated-artifacts/ICurve.json'; | ||||
| import * as IDydx from '../generated-artifacts/IDydx.json'; | ||||
| import * as IDydxBridge from '../generated-artifacts/IDydxBridge.json'; | ||||
| import * as IERC20Bridge from '../generated-artifacts/IERC20Bridge.json'; | ||||
| import * as IEth2Dai from '../generated-artifacts/IEth2Dai.json'; | ||||
| import * as IGasToken from '../generated-artifacts/IGasToken.json'; | ||||
| import * as IKyberNetworkProxy from '../generated-artifacts/IKyberNetworkProxy.json'; | ||||
| import * as IMooniswap from '../generated-artifacts/IMooniswap.json'; | ||||
| import * as IMStable from '../generated-artifacts/IMStable.json'; | ||||
| import * as IShell from '../generated-artifacts/IShell.json'; | ||||
| import * as IUniswapExchange from '../generated-artifacts/IUniswapExchange.json'; | ||||
| import * as IUniswapExchangeFactory from '../generated-artifacts/IUniswapExchangeFactory.json'; | ||||
| import * as IUniswapV2Router01 from '../generated-artifacts/IUniswapV2Router01.json'; | ||||
| import * as KyberBridge from '../generated-artifacts/KyberBridge.json'; | ||||
| import * as MixinAssetProxyDispatcher from '../generated-artifacts/MixinAssetProxyDispatcher.json'; | ||||
| import * as MixinAuthorizable from '../generated-artifacts/MixinAuthorizable.json'; | ||||
| import * as MixinGasToken from '../generated-artifacts/MixinGasToken.json'; | ||||
| import * as MooniswapBridge from '../generated-artifacts/MooniswapBridge.json'; | ||||
| import * as MStableBridge from '../generated-artifacts/MStableBridge.json'; | ||||
| import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json'; | ||||
| import * as Ownable from '../generated-artifacts/Ownable.json'; | ||||
| import * as ShellBridge from '../generated-artifacts/ShellBridge.json'; | ||||
| import * as SnowSwapBridge from '../generated-artifacts/SnowSwapBridge.json'; | ||||
| import * as StaticCallProxy from '../generated-artifacts/StaticCallProxy.json'; | ||||
| import * as SushiSwapBridge from '../generated-artifacts/SushiSwapBridge.json'; | ||||
| import * as SwerveBridge from '../generated-artifacts/SwerveBridge.json'; | ||||
| import * as TestBancorBridge from '../generated-artifacts/TestBancorBridge.json'; | ||||
| import * as TestChaiBridge from '../generated-artifacts/TestChaiBridge.json'; | ||||
| import * as TestDexForwarderBridge from '../generated-artifacts/TestDexForwarderBridge.json'; | ||||
| import * as TestDydxBridge from '../generated-artifacts/TestDydxBridge.json'; | ||||
| import * as TestERC20Bridge from '../generated-artifacts/TestERC20Bridge.json'; | ||||
| import * as TestEth2DaiBridge from '../generated-artifacts/TestEth2DaiBridge.json'; | ||||
| import * as TestKyberBridge from '../generated-artifacts/TestKyberBridge.json'; | ||||
| import * as TestStaticCallTarget from '../generated-artifacts/TestStaticCallTarget.json'; | ||||
| import * as TestUniswapBridge from '../generated-artifacts/TestUniswapBridge.json'; | ||||
| import * as TestUniswapV2Bridge from '../generated-artifacts/TestUniswapV2Bridge.json'; | ||||
| import * as UniswapBridge from '../generated-artifacts/UniswapBridge.json'; | ||||
| import * as UniswapV2Bridge from '../generated-artifacts/UniswapV2Bridge.json'; | ||||
| export const artifacts = { | ||||
|     MixinAssetProxyDispatcher: MixinAssetProxyDispatcher as ContractArtifact, | ||||
|     MixinAuthorizable: MixinAuthorizable as ContractArtifact, | ||||
| @@ -50,30 +74,54 @@ export const artifacts = { | ||||
|     ERC721Proxy: ERC721Proxy as ContractArtifact, | ||||
|     MultiAssetProxy: MultiAssetProxy as ContractArtifact, | ||||
|     StaticCallProxy: StaticCallProxy as ContractArtifact, | ||||
|     BalancerBridge: BalancerBridge as ContractArtifact, | ||||
|     BancorBridge: BancorBridge as ContractArtifact, | ||||
|     ChaiBridge: ChaiBridge as ContractArtifact, | ||||
|     CreamBridge: CreamBridge as ContractArtifact, | ||||
|     CryptoComBridge: CryptoComBridge as ContractArtifact, | ||||
|     CurveBridge: CurveBridge as ContractArtifact, | ||||
|     DODOBridge: DODOBridge as ContractArtifact, | ||||
|     DexForwarderBridge: DexForwarderBridge as ContractArtifact, | ||||
|     DydxBridge: DydxBridge as ContractArtifact, | ||||
|     Eth2DaiBridge: Eth2DaiBridge as ContractArtifact, | ||||
|     KyberBridge: KyberBridge as ContractArtifact, | ||||
|     MStableBridge: MStableBridge as ContractArtifact, | ||||
|     MixinGasToken: MixinGasToken as ContractArtifact, | ||||
|     MooniswapBridge: MooniswapBridge as ContractArtifact, | ||||
|     ShellBridge: ShellBridge as ContractArtifact, | ||||
|     SnowSwapBridge: SnowSwapBridge as ContractArtifact, | ||||
|     SushiSwapBridge: SushiSwapBridge as ContractArtifact, | ||||
|     SwerveBridge: SwerveBridge as ContractArtifact, | ||||
|     UniswapBridge: UniswapBridge as ContractArtifact, | ||||
|     UniswapV2Bridge: UniswapV2Bridge as ContractArtifact, | ||||
|     IAssetData: IAssetData as ContractArtifact, | ||||
|     IAssetProxy: IAssetProxy as ContractArtifact, | ||||
|     IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact, | ||||
|     IAuthorizable: IAuthorizable as ContractArtifact, | ||||
|     IBalancerPool: IBalancerPool as ContractArtifact, | ||||
|     IBancorNetwork: IBancorNetwork as ContractArtifact, | ||||
|     IChai: IChai as ContractArtifact, | ||||
|     ICurve: ICurve as ContractArtifact, | ||||
|     IDydx: IDydx as ContractArtifact, | ||||
|     IDydxBridge: IDydxBridge as ContractArtifact, | ||||
|     IERC20Bridge: IERC20Bridge as ContractArtifact, | ||||
|     IEth2Dai: IEth2Dai as ContractArtifact, | ||||
|     IGasToken: IGasToken as ContractArtifact, | ||||
|     IKyberNetworkProxy: IKyberNetworkProxy as ContractArtifact, | ||||
|     IMStable: IMStable as ContractArtifact, | ||||
|     IMooniswap: IMooniswap as ContractArtifact, | ||||
|     IShell: IShell as ContractArtifact, | ||||
|     IUniswapExchange: IUniswapExchange as ContractArtifact, | ||||
|     IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact, | ||||
|     IUniswapV2Router01: IUniswapV2Router01 as ContractArtifact, | ||||
|     TestBancorBridge: TestBancorBridge as ContractArtifact, | ||||
|     TestChaiBridge: TestChaiBridge as ContractArtifact, | ||||
|     TestDexForwarderBridge: TestDexForwarderBridge as ContractArtifact, | ||||
|     TestDydxBridge: TestDydxBridge as ContractArtifact, | ||||
|     TestERC20Bridge: TestERC20Bridge as ContractArtifact, | ||||
|     TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact, | ||||
|     TestKyberBridge: TestKyberBridge as ContractArtifact, | ||||
|     TestStaticCallTarget: TestStaticCallTarget as ContractArtifact, | ||||
|     TestUniswapBridge: TestUniswapBridge as ContractArtifact, | ||||
|     TestUniswapV2Bridge: TestUniswapV2Bridge as ContractArtifact, | ||||
| }; | ||||
|   | ||||
							
								
								
									
										27
									
								
								contracts/asset-proxy/src/dex_forwarder_bridge.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								contracts/asset-proxy/src/dex_forwarder_bridge.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| import { AbiEncoder, BigNumber } from '@0x/utils'; | ||||
|  | ||||
| export interface DexForwarderBridgeCall { | ||||
|     target: string; | ||||
|     inputTokenAmount: BigNumber; | ||||
|     outputTokenAmount: BigNumber; | ||||
|     bridgeData: string; | ||||
| } | ||||
|  | ||||
| export interface DexForwaderBridgeData { | ||||
|     inputToken: string; | ||||
|     calls: DexForwarderBridgeCall[]; | ||||
| } | ||||
|  | ||||
| export const dexForwarderBridgeDataEncoder = AbiEncoder.create([ | ||||
|     { name: 'inputToken', type: 'address' }, | ||||
|     { | ||||
|         name: 'calls', | ||||
|         type: 'tuple[]', | ||||
|         components: [ | ||||
|             { name: 'target', type: 'address' }, | ||||
|             { name: 'inputTokenAmount', type: 'uint256' }, | ||||
|             { name: 'outputTokenAmount', type: 'uint256' }, | ||||
|             { name: 'bridgeData', type: 'bytes' }, | ||||
|         ], | ||||
|     }, | ||||
| ]); | ||||
| @@ -1,5 +1,6 @@ | ||||
| export { artifacts } from './artifacts'; | ||||
| export { | ||||
|     BalancerBridgeContract, | ||||
|     ChaiBridgeContract, | ||||
|     ERC1155ProxyContract, | ||||
|     ERC20BridgeProxyContract, | ||||
| @@ -17,6 +18,7 @@ export { | ||||
|     TestDydxBridgeContract, | ||||
|     TestStaticCallTargetContract, | ||||
|     UniswapBridgeContract, | ||||
|     DexForwarderBridgeContract, | ||||
| } from './wrappers'; | ||||
|  | ||||
| export { ERC20Wrapper } from './erc20_wrapper'; | ||||
| @@ -88,3 +90,4 @@ export { | ||||
| } from './asset_data'; | ||||
|  | ||||
| export * from './dydx_bridge_encoder'; | ||||
| export * from './dex_forwarder_bridge'; | ||||
|   | ||||
| @@ -3,8 +3,14 @@ | ||||
|  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
| export * from '../generated-wrappers/balancer_bridge'; | ||||
| export * from '../generated-wrappers/bancor_bridge'; | ||||
| export * from '../generated-wrappers/chai_bridge'; | ||||
| export * from '../generated-wrappers/cream_bridge'; | ||||
| export * from '../generated-wrappers/crypto_com_bridge'; | ||||
| export * from '../generated-wrappers/curve_bridge'; | ||||
| export * from '../generated-wrappers/d_o_d_o_bridge'; | ||||
| export * from '../generated-wrappers/dex_forwarder_bridge'; | ||||
| export * from '../generated-wrappers/dydx_bridge'; | ||||
| export * from '../generated-wrappers/erc1155_proxy'; | ||||
| export * from '../generated-wrappers/erc20_bridge_proxy'; | ||||
| @@ -15,26 +21,44 @@ export * from '../generated-wrappers/i_asset_data'; | ||||
| export * from '../generated-wrappers/i_asset_proxy'; | ||||
| export * from '../generated-wrappers/i_asset_proxy_dispatcher'; | ||||
| export * from '../generated-wrappers/i_authorizable'; | ||||
| export * from '../generated-wrappers/i_balancer_pool'; | ||||
| export * from '../generated-wrappers/i_bancor_network'; | ||||
| export * from '../generated-wrappers/i_chai'; | ||||
| export * from '../generated-wrappers/i_curve'; | ||||
| export * from '../generated-wrappers/i_dydx'; | ||||
| export * from '../generated-wrappers/i_dydx_bridge'; | ||||
| export * from '../generated-wrappers/i_erc20_bridge'; | ||||
| export * from '../generated-wrappers/i_eth2_dai'; | ||||
| export * from '../generated-wrappers/i_gas_token'; | ||||
| export * from '../generated-wrappers/i_kyber_network_proxy'; | ||||
| export * from '../generated-wrappers/i_m_stable'; | ||||
| export * from '../generated-wrappers/i_mooniswap'; | ||||
| export * from '../generated-wrappers/i_shell'; | ||||
| export * from '../generated-wrappers/i_uniswap_exchange'; | ||||
| export * from '../generated-wrappers/i_uniswap_exchange_factory'; | ||||
| export * from '../generated-wrappers/i_uniswap_v2_router01'; | ||||
| export * from '../generated-wrappers/kyber_bridge'; | ||||
| export * from '../generated-wrappers/m_stable_bridge'; | ||||
| export * from '../generated-wrappers/mixin_asset_proxy_dispatcher'; | ||||
| export * from '../generated-wrappers/mixin_authorizable'; | ||||
| export * from '../generated-wrappers/mixin_gas_token'; | ||||
| export * from '../generated-wrappers/mooniswap_bridge'; | ||||
| export * from '../generated-wrappers/multi_asset_proxy'; | ||||
| export * from '../generated-wrappers/ownable'; | ||||
| export * from '../generated-wrappers/shell_bridge'; | ||||
| export * from '../generated-wrappers/snow_swap_bridge'; | ||||
| export * from '../generated-wrappers/static_call_proxy'; | ||||
| export * from '../generated-wrappers/sushi_swap_bridge'; | ||||
| export * from '../generated-wrappers/swerve_bridge'; | ||||
| export * from '../generated-wrappers/test_bancor_bridge'; | ||||
| export * from '../generated-wrappers/test_chai_bridge'; | ||||
| export * from '../generated-wrappers/test_dex_forwarder_bridge'; | ||||
| export * from '../generated-wrappers/test_dydx_bridge'; | ||||
| export * from '../generated-wrappers/test_erc20_bridge'; | ||||
| export * from '../generated-wrappers/test_eth2_dai_bridge'; | ||||
| export * from '../generated-wrappers/test_kyber_bridge'; | ||||
| export * from '../generated-wrappers/test_static_call_target'; | ||||
| export * from '../generated-wrappers/test_uniswap_bridge'; | ||||
| export * from '../generated-wrappers/test_uniswap_v2_bridge'; | ||||
| export * from '../generated-wrappers/uniswap_bridge'; | ||||
| export * from '../generated-wrappers/uniswap_v2_bridge'; | ||||
|   | ||||
| @@ -5,8 +5,14 @@ | ||||
|  */ | ||||
| import { ContractArtifact } from 'ethereum-types'; | ||||
|  | ||||
| import * as BalancerBridge from '../test/generated-artifacts/BalancerBridge.json'; | ||||
| import * as BancorBridge from '../test/generated-artifacts/BancorBridge.json'; | ||||
| import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.json'; | ||||
| import * as CreamBridge from '../test/generated-artifacts/CreamBridge.json'; | ||||
| import * as CryptoComBridge from '../test/generated-artifacts/CryptoComBridge.json'; | ||||
| import * as CurveBridge from '../test/generated-artifacts/CurveBridge.json'; | ||||
| import * as DexForwarderBridge from '../test/generated-artifacts/DexForwarderBridge.json'; | ||||
| import * as DODOBridge from '../test/generated-artifacts/DODOBridge.json'; | ||||
| import * as DydxBridge from '../test/generated-artifacts/DydxBridge.json'; | ||||
| import * as ERC1155Proxy from '../test/generated-artifacts/ERC1155Proxy.json'; | ||||
| import * as ERC20BridgeProxy from '../test/generated-artifacts/ERC20BridgeProxy.json'; | ||||
| @@ -17,29 +23,47 @@ import * as IAssetData from '../test/generated-artifacts/IAssetData.json'; | ||||
| import * as IAssetProxy from '../test/generated-artifacts/IAssetProxy.json'; | ||||
| import * as IAssetProxyDispatcher from '../test/generated-artifacts/IAssetProxyDispatcher.json'; | ||||
| import * as IAuthorizable from '../test/generated-artifacts/IAuthorizable.json'; | ||||
| import * as IBalancerPool from '../test/generated-artifacts/IBalancerPool.json'; | ||||
| import * as IBancorNetwork from '../test/generated-artifacts/IBancorNetwork.json'; | ||||
| import * as IChai from '../test/generated-artifacts/IChai.json'; | ||||
| import * as ICurve from '../test/generated-artifacts/ICurve.json'; | ||||
| import * as IDydx from '../test/generated-artifacts/IDydx.json'; | ||||
| import * as IDydxBridge from '../test/generated-artifacts/IDydxBridge.json'; | ||||
| import * as IERC20Bridge from '../test/generated-artifacts/IERC20Bridge.json'; | ||||
| import * as IEth2Dai from '../test/generated-artifacts/IEth2Dai.json'; | ||||
| import * as IGasToken from '../test/generated-artifacts/IGasToken.json'; | ||||
| import * as IKyberNetworkProxy from '../test/generated-artifacts/IKyberNetworkProxy.json'; | ||||
| import * as IMooniswap from '../test/generated-artifacts/IMooniswap.json'; | ||||
| import * as IMStable from '../test/generated-artifacts/IMStable.json'; | ||||
| import * as IShell from '../test/generated-artifacts/IShell.json'; | ||||
| import * as IUniswapExchange from '../test/generated-artifacts/IUniswapExchange.json'; | ||||
| import * as IUniswapExchangeFactory from '../test/generated-artifacts/IUniswapExchangeFactory.json'; | ||||
| import * as IUniswapV2Router01 from '../test/generated-artifacts/IUniswapV2Router01.json'; | ||||
| import * as KyberBridge from '../test/generated-artifacts/KyberBridge.json'; | ||||
| import * as MixinAssetProxyDispatcher from '../test/generated-artifacts/MixinAssetProxyDispatcher.json'; | ||||
| import * as MixinAuthorizable from '../test/generated-artifacts/MixinAuthorizable.json'; | ||||
| import * as MixinGasToken from '../test/generated-artifacts/MixinGasToken.json'; | ||||
| import * as MooniswapBridge from '../test/generated-artifacts/MooniswapBridge.json'; | ||||
| import * as MStableBridge from '../test/generated-artifacts/MStableBridge.json'; | ||||
| import * as MultiAssetProxy from '../test/generated-artifacts/MultiAssetProxy.json'; | ||||
| import * as Ownable from '../test/generated-artifacts/Ownable.json'; | ||||
| import * as ShellBridge from '../test/generated-artifacts/ShellBridge.json'; | ||||
| import * as SnowSwapBridge from '../test/generated-artifacts/SnowSwapBridge.json'; | ||||
| import * as StaticCallProxy from '../test/generated-artifacts/StaticCallProxy.json'; | ||||
| import * as SushiSwapBridge from '../test/generated-artifacts/SushiSwapBridge.json'; | ||||
| import * as SwerveBridge from '../test/generated-artifacts/SwerveBridge.json'; | ||||
| import * as TestBancorBridge from '../test/generated-artifacts/TestBancorBridge.json'; | ||||
| import * as TestChaiBridge from '../test/generated-artifacts/TestChaiBridge.json'; | ||||
| import * as TestDexForwarderBridge from '../test/generated-artifacts/TestDexForwarderBridge.json'; | ||||
| import * as TestDydxBridge from '../test/generated-artifacts/TestDydxBridge.json'; | ||||
| import * as TestERC20Bridge from '../test/generated-artifacts/TestERC20Bridge.json'; | ||||
| import * as TestEth2DaiBridge from '../test/generated-artifacts/TestEth2DaiBridge.json'; | ||||
| import * as TestKyberBridge from '../test/generated-artifacts/TestKyberBridge.json'; | ||||
| import * as TestStaticCallTarget from '../test/generated-artifacts/TestStaticCallTarget.json'; | ||||
| import * as TestUniswapBridge from '../test/generated-artifacts/TestUniswapBridge.json'; | ||||
| import * as TestUniswapV2Bridge from '../test/generated-artifacts/TestUniswapV2Bridge.json'; | ||||
| import * as UniswapBridge from '../test/generated-artifacts/UniswapBridge.json'; | ||||
| import * as UniswapV2Bridge from '../test/generated-artifacts/UniswapV2Bridge.json'; | ||||
| export const artifacts = { | ||||
|     MixinAssetProxyDispatcher: MixinAssetProxyDispatcher as ContractArtifact, | ||||
|     MixinAuthorizable: MixinAuthorizable as ContractArtifact, | ||||
| @@ -50,30 +74,54 @@ export const artifacts = { | ||||
|     ERC721Proxy: ERC721Proxy as ContractArtifact, | ||||
|     MultiAssetProxy: MultiAssetProxy as ContractArtifact, | ||||
|     StaticCallProxy: StaticCallProxy as ContractArtifact, | ||||
|     BalancerBridge: BalancerBridge as ContractArtifact, | ||||
|     BancorBridge: BancorBridge as ContractArtifact, | ||||
|     ChaiBridge: ChaiBridge as ContractArtifact, | ||||
|     CreamBridge: CreamBridge as ContractArtifact, | ||||
|     CryptoComBridge: CryptoComBridge as ContractArtifact, | ||||
|     CurveBridge: CurveBridge as ContractArtifact, | ||||
|     DODOBridge: DODOBridge as ContractArtifact, | ||||
|     DexForwarderBridge: DexForwarderBridge as ContractArtifact, | ||||
|     DydxBridge: DydxBridge as ContractArtifact, | ||||
|     Eth2DaiBridge: Eth2DaiBridge as ContractArtifact, | ||||
|     KyberBridge: KyberBridge as ContractArtifact, | ||||
|     MStableBridge: MStableBridge as ContractArtifact, | ||||
|     MixinGasToken: MixinGasToken as ContractArtifact, | ||||
|     MooniswapBridge: MooniswapBridge as ContractArtifact, | ||||
|     ShellBridge: ShellBridge as ContractArtifact, | ||||
|     SnowSwapBridge: SnowSwapBridge as ContractArtifact, | ||||
|     SushiSwapBridge: SushiSwapBridge as ContractArtifact, | ||||
|     SwerveBridge: SwerveBridge as ContractArtifact, | ||||
|     UniswapBridge: UniswapBridge as ContractArtifact, | ||||
|     UniswapV2Bridge: UniswapV2Bridge as ContractArtifact, | ||||
|     IAssetData: IAssetData as ContractArtifact, | ||||
|     IAssetProxy: IAssetProxy as ContractArtifact, | ||||
|     IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact, | ||||
|     IAuthorizable: IAuthorizable as ContractArtifact, | ||||
|     IBalancerPool: IBalancerPool as ContractArtifact, | ||||
|     IBancorNetwork: IBancorNetwork as ContractArtifact, | ||||
|     IChai: IChai as ContractArtifact, | ||||
|     ICurve: ICurve as ContractArtifact, | ||||
|     IDydx: IDydx as ContractArtifact, | ||||
|     IDydxBridge: IDydxBridge as ContractArtifact, | ||||
|     IERC20Bridge: IERC20Bridge as ContractArtifact, | ||||
|     IEth2Dai: IEth2Dai as ContractArtifact, | ||||
|     IGasToken: IGasToken as ContractArtifact, | ||||
|     IKyberNetworkProxy: IKyberNetworkProxy as ContractArtifact, | ||||
|     IMStable: IMStable as ContractArtifact, | ||||
|     IMooniswap: IMooniswap as ContractArtifact, | ||||
|     IShell: IShell as ContractArtifact, | ||||
|     IUniswapExchange: IUniswapExchange as ContractArtifact, | ||||
|     IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact, | ||||
|     IUniswapV2Router01: IUniswapV2Router01 as ContractArtifact, | ||||
|     TestBancorBridge: TestBancorBridge as ContractArtifact, | ||||
|     TestChaiBridge: TestChaiBridge as ContractArtifact, | ||||
|     TestDexForwarderBridge: TestDexForwarderBridge as ContractArtifact, | ||||
|     TestDydxBridge: TestDydxBridge as ContractArtifact, | ||||
|     TestERC20Bridge: TestERC20Bridge as ContractArtifact, | ||||
|     TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact, | ||||
|     TestKyberBridge: TestKyberBridge as ContractArtifact, | ||||
|     TestStaticCallTarget: TestStaticCallTarget as ContractArtifact, | ||||
|     TestUniswapBridge: TestUniswapBridge as ContractArtifact, | ||||
|     TestUniswapV2Bridge: TestUniswapV2Bridge as ContractArtifact, | ||||
| }; | ||||
|   | ||||
							
								
								
									
										185
									
								
								contracts/asset-proxy/test/bancor_bridge.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								contracts/asset-proxy/test/bancor_bridge.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,185 @@ | ||||
| import { | ||||
|     blockchainTests, | ||||
|     constants, | ||||
|     expect, | ||||
|     filterLogsToArguments, | ||||
|     getRandomInteger, | ||||
|     randomAddress, | ||||
| } from '@0x/contracts-test-utils'; | ||||
| import { AssetProxyId } from '@0x/types'; | ||||
| import { AbiEncoder, BigNumber, hexUtils } from '@0x/utils'; | ||||
| import { DecodedLogs } from 'ethereum-types'; | ||||
| import * as _ from 'lodash'; | ||||
|  | ||||
| import { artifacts } from './artifacts'; | ||||
| import { TestBancorBridgeContract } from './generated-wrappers/test_bancor_bridge'; | ||||
| import { | ||||
|     TestBancorBridgeConvertByPathInputEventArgs as ConvertByPathArgs, | ||||
|     TestBancorBridgeEvents as ContractEvents, | ||||
|     TestBancorBridgeTokenApproveEventArgs as TokenApproveArgs, | ||||
| } from './wrappers'; | ||||
|  | ||||
| blockchainTests.resets('Bancor unit tests', env => { | ||||
|     const FROM_TOKEN_DECIMALS = 6; | ||||
|     const TO_TOKEN_DECIMALS = 18; | ||||
|     const FROM_TOKEN_BASE = new BigNumber(10).pow(FROM_TOKEN_DECIMALS); | ||||
|     const TO_TOKEN_BASE = new BigNumber(10).pow(TO_TOKEN_DECIMALS); | ||||
|     let testContract: TestBancorBridgeContract; | ||||
|  | ||||
|     before(async () => { | ||||
|         testContract = await TestBancorBridgeContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.TestBancorBridge, | ||||
|             env.provider, | ||||
|             env.txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|     }); | ||||
|  | ||||
|     describe('isValidSignature()', () => { | ||||
|         it('returns success bytes', async () => { | ||||
|             const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381'; | ||||
|             const result = await testContract | ||||
|                 .isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32))) | ||||
|                 .callAsync(); | ||||
|             expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('bridgeTransferFrom()', () => { | ||||
|         interface TransferFromOpts { | ||||
|             tokenAddressesPath: string[]; | ||||
|             toAddress: string; | ||||
|             // Amount to pass into `bridgeTransferFrom()` | ||||
|             amount: BigNumber; | ||||
|             // Token balance of the bridge. | ||||
|             fromTokenBalance: BigNumber; | ||||
|             // Router reverts with this reason | ||||
|             routerRevertReason: string; | ||||
|         } | ||||
|  | ||||
|         interface TransferFromResult { | ||||
|             opts: TransferFromOpts; | ||||
|             result: string; | ||||
|             logs: DecodedLogs; | ||||
|             blocktime: number; | ||||
|         } | ||||
|  | ||||
|         function createTransferFromOpts(opts?: Partial<TransferFromOpts>): TransferFromOpts { | ||||
|             const amount = getRandomInteger(1, TO_TOKEN_BASE.times(100)); | ||||
|             return { | ||||
|                 tokenAddressesPath: Array(3).fill(constants.NULL_ADDRESS), | ||||
|                 amount, | ||||
|                 toAddress: randomAddress(), | ||||
|                 fromTokenBalance: getRandomInteger(1, FROM_TOKEN_BASE.times(100)), | ||||
|                 routerRevertReason: '', | ||||
|                 ...opts, | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         const bridgeDataEncoder = AbiEncoder.create('(address[], address)'); | ||||
|  | ||||
|         async function transferFromAsync(opts?: Partial<TransferFromOpts>): Promise<TransferFromResult> { | ||||
|             const _opts = createTransferFromOpts(opts); | ||||
|  | ||||
|             for (let i = 0; i < _opts.tokenAddressesPath.length; i++) { | ||||
|                 const createFromTokenFn = testContract.createToken(_opts.tokenAddressesPath[i]); | ||||
|                 _opts.tokenAddressesPath[i] = await createFromTokenFn.callAsync(); | ||||
|                 await createFromTokenFn.awaitTransactionSuccessAsync(); | ||||
|             } | ||||
|  | ||||
|             // Set the token balance for the token we're converting from. | ||||
|             await testContract | ||||
|                 .setTokenBalance(_opts.tokenAddressesPath[0], _opts.fromTokenBalance) | ||||
|                 .awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             // Set revert reason for the router. | ||||
|             await testContract.setNetworkRevertReason(_opts.routerRevertReason).awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             // Call bridgeTransferFrom(). | ||||
|             const bridgeTransferFromFn = testContract.bridgeTransferFrom( | ||||
|                 // Output token | ||||
|                 _opts.tokenAddressesPath[_opts.tokenAddressesPath.length - 1], | ||||
|                 // Random maker address. | ||||
|                 randomAddress(), | ||||
|                 // Recipient address. | ||||
|                 _opts.toAddress, | ||||
|                 // Transfer amount. | ||||
|                 _opts.amount, | ||||
|                 // ABI-encode the input token address as the bridge data. | ||||
|                 bridgeDataEncoder.encode([ | ||||
|                     _opts.tokenAddressesPath, | ||||
|                     await testContract.getNetworkAddress().callAsync(), | ||||
|                 ]), | ||||
|             ); | ||||
|             const result = await bridgeTransferFromFn.callAsync(); | ||||
|             const receipt = await bridgeTransferFromFn.awaitTransactionSuccessAsync(); | ||||
|             return { | ||||
|                 opts: _opts, | ||||
|                 result, | ||||
|                 logs: (receipt.logs as any) as DecodedLogs, | ||||
|                 blocktime: await env.web3Wrapper.getBlockTimestampAsync(receipt.blockNumber), | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         it('returns magic bytes on success', async () => { | ||||
|             const { result } = await transferFromAsync(); | ||||
|             expect(result).to.eq(AssetProxyId.ERC20Bridge); | ||||
|         }); | ||||
|  | ||||
|         describe('token -> token', async () => { | ||||
|             it('calls BancorNetwork.convertByPath()', async () => { | ||||
|                 const { opts, result, logs } = await transferFromAsync(); | ||||
|                 expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id'); | ||||
|                 const transfers = filterLogsToArguments<ConvertByPathArgs>(logs, ContractEvents.ConvertByPathInput); | ||||
|  | ||||
|                 expect(transfers.length).to.eq(1); | ||||
|                 expect(transfers[0].toTokenAddress).to.eq( | ||||
|                     opts.tokenAddressesPath[opts.tokenAddressesPath.length - 1], | ||||
|                     'output token address', | ||||
|                 ); | ||||
|                 expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address'); | ||||
|                 expect(transfers[0].amountIn).to.bignumber.eq(opts.fromTokenBalance, 'input token amount'); | ||||
|                 expect(transfers[0].amountOutMin).to.bignumber.eq(opts.amount, 'output token amount'); | ||||
|                 expect(transfers[0].feeRecipient).to.eq(constants.NULL_ADDRESS); | ||||
|                 expect(transfers[0].feeAmount).to.bignumber.eq(new BigNumber(0)); | ||||
|             }); | ||||
|  | ||||
|             it('sets allowance for "from" token', async () => { | ||||
|                 const { logs } = await transferFromAsync(); | ||||
|                 const approvals = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove); | ||||
|                 const networkAddress = await testContract.getNetworkAddress().callAsync(); | ||||
|                 expect(approvals.length).to.eq(1); | ||||
|                 expect(approvals[0].spender).to.eq(networkAddress); | ||||
|                 expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256); | ||||
|             }); | ||||
|  | ||||
|             it('fails if the router fails', async () => { | ||||
|                 const revertReason = 'FOOBAR'; | ||||
|                 const tx = transferFromAsync({ | ||||
|                     routerRevertReason: revertReason, | ||||
|                 }); | ||||
|                 return expect(tx).to.eventually.be.rejectedWith(revertReason); | ||||
|             }); | ||||
|         }); | ||||
|         describe('token -> token -> token', async () => { | ||||
|             it('calls BancorNetwork.convertByPath()', async () => { | ||||
|                 const { opts, result, logs } = await transferFromAsync({ | ||||
|                     tokenAddressesPath: Array(5).fill(constants.NULL_ADDRESS), | ||||
|                 }); | ||||
|                 expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id'); | ||||
|                 const transfers = filterLogsToArguments<ConvertByPathArgs>(logs, ContractEvents.ConvertByPathInput); | ||||
|  | ||||
|                 expect(transfers.length).to.eq(1); | ||||
|                 expect(transfers[0].toTokenAddress).to.eq( | ||||
|                     opts.tokenAddressesPath[opts.tokenAddressesPath.length - 1], | ||||
|                     'output token address', | ||||
|                 ); | ||||
|                 expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address'); | ||||
|                 expect(transfers[0].amountIn).to.bignumber.eq(opts.fromTokenBalance, 'input token amount'); | ||||
|                 expect(transfers[0].amountOutMin).to.bignumber.eq(opts.amount, 'output token amount'); | ||||
|                 expect(transfers[0].feeRecipient).to.eq(constants.NULL_ADDRESS); | ||||
|                 expect(transfers[0].feeAmount).to.bignumber.eq(new BigNumber(0)); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										354
									
								
								contracts/asset-proxy/test/dex_forwarder_bridge.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										354
									
								
								contracts/asset-proxy/test/dex_forwarder_bridge.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,354 @@ | ||||
| import { ContractTxFunctionObj } from '@0x/contract-wrappers'; | ||||
| import { | ||||
|     blockchainTests, | ||||
|     constants, | ||||
|     expect, | ||||
|     filterLogsToArguments, | ||||
|     getRandomInteger, | ||||
|     randomAddress, | ||||
|     shortZip, | ||||
| } from '@0x/contracts-test-utils'; | ||||
| import { BigNumber, hexUtils, NULL_ADDRESS } from '@0x/utils'; | ||||
| import { DecodedLogs } from 'ethereum-types'; | ||||
| import * as _ from 'lodash'; | ||||
|  | ||||
| import { DexForwarderBridgeCall, dexForwarderBridgeDataEncoder } from '../src/dex_forwarder_bridge'; | ||||
|  | ||||
| import { artifacts } from './artifacts'; | ||||
| import { | ||||
|     TestDexForwarderBridgeBridgeTransferFromCalledEventArgs as BtfCalledEventArgs, | ||||
|     TestDexForwarderBridgeContract, | ||||
|     TestDexForwarderBridgeEvents as TestEvents, | ||||
| } from './wrappers'; | ||||
|  | ||||
| const { ZERO_AMOUNT } = constants; | ||||
|  | ||||
| blockchainTests.resets('DexForwarderBridge unit tests', env => { | ||||
|     let testContract: TestDexForwarderBridgeContract; | ||||
|     let inputToken: string; | ||||
|     let outputToken: string; | ||||
|     const BRIDGE_SUCCESS = '0xdc1600f3'; | ||||
|     const BRIDGE_FAILURE = '0xffffffff'; | ||||
|     const BRIDGE_REVERT_ERROR = 'oopsie'; | ||||
|     const NOT_AUTHORIZED_REVERT = 'DexForwarderBridge/SENDER_NOT_AUTHORIZED'; | ||||
|     const DEFAULTS = { | ||||
|         toAddress: randomAddress(), | ||||
|     }; | ||||
|  | ||||
|     before(async () => { | ||||
|         testContract = await TestDexForwarderBridgeContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.TestDexForwarderBridge, | ||||
|             env.provider, | ||||
|             env.txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         // Create test tokens. | ||||
|         [inputToken, outputToken] = [ | ||||
|             await callAndTransactAsync(testContract.createToken()), | ||||
|             await callAndTransactAsync(testContract.createToken()), | ||||
|         ]; | ||||
|         await callAndTransactAsync(testContract.setAuthorized(env.txDefaults.from as string)); | ||||
|     }); | ||||
|  | ||||
|     async function callAndTransactAsync<TResult>(fnCall: ContractTxFunctionObj<TResult>): Promise<TResult> { | ||||
|         const result = await fnCall.callAsync(); | ||||
|         await fnCall.awaitTransactionSuccessAsync({}, { shouldValidate: false }); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     function getRandomBridgeCall( | ||||
|         bridgeAddress: string, | ||||
|         fields: Partial<DexForwarderBridgeCall> = {}, | ||||
|     ): DexForwarderBridgeCall { | ||||
|         return { | ||||
|             target: bridgeAddress, | ||||
|             inputTokenAmount: getRandomInteger(1, '100e18'), | ||||
|             outputTokenAmount: getRandomInteger(1, '100e18'), | ||||
|             bridgeData: hexUtils.leftPad(inputToken), | ||||
|             ...fields, | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     describe('bridgeTransferFrom()', () => { | ||||
|         let goodBridgeCalls: DexForwarderBridgeCall[]; | ||||
|         let revertingBridgeCall: DexForwarderBridgeCall; | ||||
|         let failingBridgeCall: DexForwarderBridgeCall; | ||||
|         let allBridgeCalls: DexForwarderBridgeCall[]; | ||||
|         let totalFillableOutputAmount: BigNumber; | ||||
|         let totalFillableInputAmount: BigNumber; | ||||
|         let recipientOutputBalance: BigNumber; | ||||
|  | ||||
|         beforeEach(async () => { | ||||
|             goodBridgeCalls = []; | ||||
|             for (let i = 0; i < 4; ++i) { | ||||
|                 goodBridgeCalls.push(await createBridgeCallAsync({ returnCode: BRIDGE_SUCCESS })); | ||||
|             } | ||||
|             revertingBridgeCall = await createBridgeCallAsync({ revertError: BRIDGE_REVERT_ERROR }); | ||||
|             failingBridgeCall = await createBridgeCallAsync({ returnCode: BRIDGE_FAILURE }); | ||||
|             allBridgeCalls = _.shuffle([failingBridgeCall, revertingBridgeCall, ...goodBridgeCalls]); | ||||
|  | ||||
|             totalFillableInputAmount = BigNumber.sum(...goodBridgeCalls.map(c => c.inputTokenAmount)); | ||||
|             totalFillableOutputAmount = BigNumber.sum(...goodBridgeCalls.map(c => c.outputTokenAmount)); | ||||
|  | ||||
|             // Grant the taker some output tokens. | ||||
|             await testContract.setTokenBalance( | ||||
|                 outputToken, | ||||
|                 DEFAULTS.toAddress, | ||||
|                 (recipientOutputBalance = getRandomInteger(1, '100e18')), | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         async function setForwarderInputBalanceAsync(amount: BigNumber): Promise<void> { | ||||
|             await testContract | ||||
|                 .setTokenBalance(inputToken, testContract.address, amount) | ||||
|                 .awaitTransactionSuccessAsync({}, { shouldValidate: false }); | ||||
|         } | ||||
|  | ||||
|         async function createBridgeCallAsync( | ||||
|             opts: Partial<{ | ||||
|                 returnCode: string; | ||||
|                 revertError: string; | ||||
|                 callFields: Partial<DexForwarderBridgeCall>; | ||||
|                 outputFillAmount: BigNumber; | ||||
|             }>, | ||||
|         ): Promise<DexForwarderBridgeCall> { | ||||
|             const { returnCode, revertError, callFields, outputFillAmount } = { | ||||
|                 returnCode: BRIDGE_SUCCESS, | ||||
|                 revertError: '', | ||||
|                 ...opts, | ||||
|             }; | ||||
|             const bridge = await callAndTransactAsync(testContract.createBridge(returnCode, revertError)); | ||||
|             const call = getRandomBridgeCall(bridge, callFields); | ||||
|             await testContract | ||||
|                 .setBridgeTransferAmount(call.target, outputFillAmount || call.outputTokenAmount) | ||||
|                 .awaitTransactionSuccessAsync({}, { shouldValidate: false }); | ||||
|             return call; | ||||
|         } | ||||
|  | ||||
|         async function callBridgeTransferFromAsync(opts: { | ||||
|             bridgeData: string; | ||||
|             sellAmount?: BigNumber; | ||||
|             buyAmount?: BigNumber; | ||||
|         }): Promise<DecodedLogs> { | ||||
|             // Fund the forwarder with input tokens to sell. | ||||
|             await setForwarderInputBalanceAsync(opts.sellAmount || totalFillableInputAmount); | ||||
|             const call = testContract.bridgeTransferFrom( | ||||
|                 outputToken, | ||||
|                 testContract.address, | ||||
|                 DEFAULTS.toAddress, | ||||
|                 opts.buyAmount || totalFillableOutputAmount, | ||||
|                 opts.bridgeData, | ||||
|             ); | ||||
|             const returnCode = await call.callAsync(); | ||||
|             if (returnCode !== BRIDGE_SUCCESS) { | ||||
|                 throw new Error('Expected BRIDGE_SUCCESS'); | ||||
|             } | ||||
|             const receipt = await call.awaitTransactionSuccessAsync({}, { shouldValidate: false }); | ||||
|             // tslint:disable-next-line: no-unnecessary-type-assertion | ||||
|             return receipt.logs as DecodedLogs; | ||||
|         } | ||||
|  | ||||
|         it('succeeds with no bridge calls and no input balance', async () => { | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls: [], | ||||
|             }); | ||||
|             await callBridgeTransferFromAsync({ bridgeData, sellAmount: ZERO_AMOUNT }); | ||||
|         }); | ||||
|  | ||||
|         it('succeeds with bridge calls and no input balance', async () => { | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls: allBridgeCalls, | ||||
|             }); | ||||
|             await callBridgeTransferFromAsync({ bridgeData, sellAmount: ZERO_AMOUNT }); | ||||
|         }); | ||||
|  | ||||
|         it('succeeds with no bridge calls and an input balance', async () => { | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls: [], | ||||
|             }); | ||||
|             await callBridgeTransferFromAsync({ | ||||
|                 bridgeData, | ||||
|                 sellAmount: new BigNumber(1), | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         it('succeeds if entire input token balance is not consumed', async () => { | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls: allBridgeCalls, | ||||
|             }); | ||||
|             await callBridgeTransferFromAsync({ | ||||
|                 bridgeData, | ||||
|                 sellAmount: totalFillableInputAmount.plus(1), | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         it('fails if not authorized', async () => { | ||||
|             const calls = goodBridgeCalls.slice(0, 1); | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls, | ||||
|             }); | ||||
|             await callAndTransactAsync(testContract.setAuthorized(NULL_ADDRESS)); | ||||
|             return expect(callBridgeTransferFromAsync({ bridgeData, sellAmount: new BigNumber(1) })).to.revertWith( | ||||
|                 NOT_AUTHORIZED_REVERT, | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it('succeeds with one bridge call', async () => { | ||||
|             const calls = goodBridgeCalls.slice(0, 1); | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls, | ||||
|             }); | ||||
|             await callBridgeTransferFromAsync({ bridgeData, sellAmount: calls[0].inputTokenAmount }); | ||||
|         }); | ||||
|  | ||||
|         it('succeeds with many bridge calls', async () => { | ||||
|             const calls = goodBridgeCalls; | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls, | ||||
|             }); | ||||
|             await callBridgeTransferFromAsync({ bridgeData }); | ||||
|         }); | ||||
|  | ||||
|         it('swallows a failing bridge call', async () => { | ||||
|             const calls = _.shuffle([...goodBridgeCalls, failingBridgeCall]); | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls, | ||||
|             }); | ||||
|             await callBridgeTransferFromAsync({ bridgeData }); | ||||
|         }); | ||||
|  | ||||
|         it('consumes input tokens for output tokens', async () => { | ||||
|             const calls = allBridgeCalls; | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls, | ||||
|             }); | ||||
|             await callBridgeTransferFromAsync({ bridgeData }); | ||||
|             const currentBridgeInputBalance = await testContract | ||||
|                 .balanceOf(inputToken, testContract.address) | ||||
|                 .callAsync(); | ||||
|             expect(currentBridgeInputBalance).to.bignumber.eq(0); | ||||
|             const currentRecipientOutputBalance = await testContract | ||||
|                 .balanceOf(outputToken, DEFAULTS.toAddress) | ||||
|                 .callAsync(); | ||||
|             expect(currentRecipientOutputBalance).to.bignumber.eq(totalFillableOutputAmount); | ||||
|         }); | ||||
|  | ||||
|         it("transfers only up to each call's input amount to each bridge", async () => { | ||||
|             const calls = goodBridgeCalls; | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls, | ||||
|             }); | ||||
|             const logs = await callBridgeTransferFromAsync({ bridgeData }); | ||||
|             const btfs = filterLogsToArguments<BtfCalledEventArgs>(logs, TestEvents.BridgeTransferFromCalled); | ||||
|             for (const [call, btf] of shortZip(goodBridgeCalls, btfs)) { | ||||
|                 expect(btf.inputTokenBalance).to.bignumber.eq(call.inputTokenAmount); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         it('transfers only up to outstanding sell amount to each bridge', async () => { | ||||
|             // Prepend an extra bridge call. | ||||
|             const calls = [ | ||||
|                 await createBridgeCallAsync({ | ||||
|                     callFields: { | ||||
|                         inputTokenAmount: new BigNumber(1), | ||||
|                         outputTokenAmount: new BigNumber(1), | ||||
|                     }, | ||||
|                 }), | ||||
|                 ...goodBridgeCalls, | ||||
|             ]; | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls, | ||||
|             }); | ||||
|             const logs = await callBridgeTransferFromAsync({ bridgeData }); | ||||
|             const btfs = filterLogsToArguments<BtfCalledEventArgs>(logs, TestEvents.BridgeTransferFromCalled); | ||||
|             expect(btfs).to.be.length(goodBridgeCalls.length + 1); | ||||
|             // The last call will receive 1 less token. | ||||
|             const lastCall = calls.slice(-1)[0]; | ||||
|             const lastBtf = btfs.slice(-1)[0]; | ||||
|             expect(lastBtf.inputTokenBalance).to.bignumber.eq(lastCall.inputTokenAmount.minus(1)); | ||||
|         }); | ||||
|  | ||||
|         it('recoups funds from a bridge that fails', async () => { | ||||
|             // Prepend a call that will take the whole input amount but will | ||||
|             // fail. | ||||
|             const badCall = await createBridgeCallAsync({ | ||||
|                 callFields: { inputTokenAmount: totalFillableInputAmount }, | ||||
|                 returnCode: BRIDGE_FAILURE, | ||||
|             }); | ||||
|             const calls = [badCall, ...goodBridgeCalls]; | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls, | ||||
|             }); | ||||
|             const logs = await callBridgeTransferFromAsync({ bridgeData }); | ||||
|             const btfs = filterLogsToArguments<BtfCalledEventArgs>(logs, TestEvents.BridgeTransferFromCalled); | ||||
|             expect(btfs).to.be.length(goodBridgeCalls.length); | ||||
|         }); | ||||
|  | ||||
|         it('recoups funds from a bridge that reverts', async () => { | ||||
|             // Prepend a call that will take the whole input amount but will | ||||
|             // revert. | ||||
|             const badCall = await createBridgeCallAsync({ | ||||
|                 callFields: { inputTokenAmount: totalFillableInputAmount }, | ||||
|                 revertError: BRIDGE_REVERT_ERROR, | ||||
|             }); | ||||
|             const calls = [badCall, ...goodBridgeCalls]; | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls, | ||||
|             }); | ||||
|             const logs = await callBridgeTransferFromAsync({ bridgeData }); | ||||
|             const btfs = filterLogsToArguments<BtfCalledEventArgs>(logs, TestEvents.BridgeTransferFromCalled); | ||||
|             expect(btfs).to.be.length(goodBridgeCalls.length); | ||||
|         }); | ||||
|  | ||||
|         it('recoups funds from a bridge that under-pays', async () => { | ||||
|             // Prepend a call that will take the whole input amount but will | ||||
|             // underpay the output amount.. | ||||
|             const badCall = await createBridgeCallAsync({ | ||||
|                 callFields: { | ||||
|                     inputTokenAmount: totalFillableInputAmount, | ||||
|                     outputTokenAmount: new BigNumber(2), | ||||
|                 }, | ||||
|                 outputFillAmount: new BigNumber(1), | ||||
|             }); | ||||
|             const calls = [badCall, ...goodBridgeCalls]; | ||||
|             const bridgeData = dexForwarderBridgeDataEncoder.encode({ | ||||
|                 inputToken, | ||||
|                 calls, | ||||
|             }); | ||||
|             const logs = await callBridgeTransferFromAsync({ bridgeData }); | ||||
|             const btfs = filterLogsToArguments<BtfCalledEventArgs>(logs, TestEvents.BridgeTransferFromCalled); | ||||
|             expect(btfs).to.be.length(goodBridgeCalls.length); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('executeBridgeCall()', () => { | ||||
|         it('cannot be called externally', async () => { | ||||
|             return expect( | ||||
|                 testContract | ||||
|                     .executeBridgeCall( | ||||
|                         randomAddress(), | ||||
|                         randomAddress(), | ||||
|                         randomAddress(), | ||||
|                         randomAddress(), | ||||
|                         new BigNumber(1), | ||||
|                         new BigNumber(1), | ||||
|                         constants.NULL_BYTES, | ||||
|                     ) | ||||
|                     .callAsync(), | ||||
|             ).to.revertWith('DexForwarderBridge/ONLY_SELF'); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -16,7 +16,8 @@ import { artifacts } from './artifacts'; | ||||
|  | ||||
| import { TestKyberBridgeContract, TestKyberBridgeEvents } from './wrappers'; | ||||
|  | ||||
| blockchainTests.resets('KyberBridge unit tests', env => { | ||||
| // TODO(dorothy-zbornak): Tests need to be updated. | ||||
| blockchainTests.resets.skip('KyberBridge unit tests', env => { | ||||
|     const KYBER_ETH_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'; | ||||
|     const FROM_TOKEN_DECIMALS = 6; | ||||
|     const TO_TOKEN_DECIMALS = 18; | ||||
| @@ -115,7 +116,7 @@ blockchainTests.resets('KyberBridge unit tests', env => { | ||||
|                 // Transfer amount. | ||||
|                 _opts.amount, | ||||
|                 // ABI-encode the input token address as the bridge data. | ||||
|                 hexUtils.leftPad(_opts.fromTokenAddress), | ||||
|                 hexUtils.concat(hexUtils.leftPad(_opts.fromTokenAddress), hexUtils.leftPad(32), hexUtils.leftPad(0)), | ||||
|             ); | ||||
|             const result = await bridgeTransferFromFn.callAsync(); | ||||
|             const { logs } = await bridgeTransferFromFn.awaitTransactionSuccessAsync(); | ||||
|   | ||||
							
								
								
									
										216
									
								
								contracts/asset-proxy/test/uniswapv2_bridge.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								contracts/asset-proxy/test/uniswapv2_bridge.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,216 @@ | ||||
| import { | ||||
|     blockchainTests, | ||||
|     constants, | ||||
|     expect, | ||||
|     filterLogsToArguments, | ||||
|     getRandomInteger, | ||||
|     randomAddress, | ||||
| } from '@0x/contracts-test-utils'; | ||||
| import { AssetProxyId } from '@0x/types'; | ||||
| import { AbiEncoder, BigNumber, hexUtils } from '@0x/utils'; | ||||
| import { DecodedLogs } from 'ethereum-types'; | ||||
| import * as _ from 'lodash'; | ||||
|  | ||||
| import { artifacts } from './artifacts'; | ||||
|  | ||||
| import { | ||||
|     TestUniswapV2BridgeContract, | ||||
|     TestUniswapV2BridgeEvents as ContractEvents, | ||||
|     TestUniswapV2BridgeSwapExactTokensForTokensInputEventArgs as SwapExactTokensForTokensArgs, | ||||
|     TestUniswapV2BridgeTokenApproveEventArgs as TokenApproveArgs, | ||||
|     TestUniswapV2BridgeTokenTransferEventArgs as TokenTransferArgs, | ||||
| } from './wrappers'; | ||||
|  | ||||
| blockchainTests.resets('UniswapV2 unit tests', env => { | ||||
|     const FROM_TOKEN_DECIMALS = 6; | ||||
|     const TO_TOKEN_DECIMALS = 18; | ||||
|     const FROM_TOKEN_BASE = new BigNumber(10).pow(FROM_TOKEN_DECIMALS); | ||||
|     const TO_TOKEN_BASE = new BigNumber(10).pow(TO_TOKEN_DECIMALS); | ||||
|     let testContract: TestUniswapV2BridgeContract; | ||||
|  | ||||
|     before(async () => { | ||||
|         testContract = await TestUniswapV2BridgeContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.TestUniswapV2Bridge, | ||||
|             env.provider, | ||||
|             env.txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|     }); | ||||
|  | ||||
|     describe('isValidSignature()', () => { | ||||
|         it('returns success bytes', async () => { | ||||
|             const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381'; | ||||
|             const result = await testContract | ||||
|                 .isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32))) | ||||
|                 .callAsync(); | ||||
|             expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('bridgeTransferFrom()', () => { | ||||
|         interface TransferFromOpts { | ||||
|             tokenAddressesPath: string[]; | ||||
|             toAddress: string; | ||||
|             // Amount to pass into `bridgeTransferFrom()` | ||||
|             amount: BigNumber; | ||||
|             // Token balance of the bridge. | ||||
|             fromTokenBalance: BigNumber; | ||||
|             // Router reverts with this reason | ||||
|             routerRevertReason: string; | ||||
|         } | ||||
|  | ||||
|         interface TransferFromResult { | ||||
|             opts: TransferFromOpts; | ||||
|             result: string; | ||||
|             logs: DecodedLogs; | ||||
|             blocktime: number; | ||||
|         } | ||||
|  | ||||
|         function createTransferFromOpts(opts?: Partial<TransferFromOpts>): TransferFromOpts { | ||||
|             const amount = getRandomInteger(1, TO_TOKEN_BASE.times(100)); | ||||
|             return { | ||||
|                 tokenAddressesPath: Array(2).fill(constants.NULL_ADDRESS), | ||||
|                 amount, | ||||
|                 toAddress: randomAddress(), | ||||
|                 fromTokenBalance: getRandomInteger(1, FROM_TOKEN_BASE.times(100)), | ||||
|                 routerRevertReason: '', | ||||
|                 ...opts, | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         const bridgeDataEncoder = AbiEncoder.create('(address[])'); | ||||
|  | ||||
|         async function transferFromAsync(opts?: Partial<TransferFromOpts>): Promise<TransferFromResult> { | ||||
|             const _opts = createTransferFromOpts(opts); | ||||
|  | ||||
|             for (let i = 0; i < _opts.tokenAddressesPath.length; i++) { | ||||
|                 const createFromTokenFn = testContract.createToken(_opts.tokenAddressesPath[i]); | ||||
|                 _opts.tokenAddressesPath[i] = await createFromTokenFn.callAsync(); | ||||
|                 await createFromTokenFn.awaitTransactionSuccessAsync(); | ||||
|             } | ||||
|  | ||||
|             // Set the token balance for the token we're converting from. | ||||
|             await testContract | ||||
|                 .setTokenBalance(_opts.tokenAddressesPath[0], _opts.fromTokenBalance) | ||||
|                 .awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             // Set revert reason for the router. | ||||
|             await testContract.setRouterRevertReason(_opts.routerRevertReason).awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             // Call bridgeTransferFrom(). | ||||
|             const bridgeTransferFromFn = testContract.bridgeTransferFrom( | ||||
|                 // Output token | ||||
|                 _opts.tokenAddressesPath[_opts.tokenAddressesPath.length - 1], | ||||
|                 // Random maker address. | ||||
|                 randomAddress(), | ||||
|                 // Recipient address. | ||||
|                 _opts.toAddress, | ||||
|                 // Transfer amount. | ||||
|                 _opts.amount, | ||||
|                 // ABI-encode the input token address as the bridge data. // FIXME | ||||
|                 bridgeDataEncoder.encode([_opts.tokenAddressesPath]), | ||||
|             ); | ||||
|             const result = await bridgeTransferFromFn.callAsync(); | ||||
|             const receipt = await bridgeTransferFromFn.awaitTransactionSuccessAsync(); | ||||
|             return { | ||||
|                 opts: _opts, | ||||
|                 result, | ||||
|                 logs: (receipt.logs as any) as DecodedLogs, | ||||
|                 blocktime: await env.web3Wrapper.getBlockTimestampAsync(receipt.blockNumber), | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         it('returns magic bytes on success', async () => { | ||||
|             const { result } = await transferFromAsync(); | ||||
|             expect(result).to.eq(AssetProxyId.ERC20Bridge); | ||||
|         }); | ||||
|  | ||||
|         it('performs transfer when both tokens are the same', async () => { | ||||
|             const createTokenFn = testContract.createToken(constants.NULL_ADDRESS); | ||||
|             const tokenAddress = await createTokenFn.callAsync(); | ||||
|             await createTokenFn.awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             const { opts, result, logs } = await transferFromAsync({ | ||||
|                 tokenAddressesPath: [tokenAddress, tokenAddress], | ||||
|             }); | ||||
|             expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id'); | ||||
|             const transfers = filterLogsToArguments<TokenTransferArgs>(logs, ContractEvents.TokenTransfer); | ||||
|  | ||||
|             expect(transfers.length).to.eq(1); | ||||
|             expect(transfers[0].token).to.eq(tokenAddress, 'input token address'); | ||||
|             expect(transfers[0].from).to.eq(testContract.address); | ||||
|             expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address'); | ||||
|             expect(transfers[0].amount).to.bignumber.eq(opts.amount, 'amount'); | ||||
|         }); | ||||
|  | ||||
|         describe('token -> token', async () => { | ||||
|             it('calls UniswapV2Router01.swapExactTokensForTokens()', async () => { | ||||
|                 const { opts, result, logs, blocktime } = await transferFromAsync(); | ||||
|                 expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id'); | ||||
|                 const transfers = filterLogsToArguments<SwapExactTokensForTokensArgs>( | ||||
|                     logs, | ||||
|                     ContractEvents.SwapExactTokensForTokensInput, | ||||
|                 ); | ||||
|  | ||||
|                 expect(transfers.length).to.eq(1); | ||||
|                 expect(transfers[0].toTokenAddress).to.eq( | ||||
|                     opts.tokenAddressesPath[opts.tokenAddressesPath.length - 1], | ||||
|                     'output token address', | ||||
|                 ); | ||||
|                 expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address'); | ||||
|                 expect(transfers[0].amountIn).to.bignumber.eq(opts.fromTokenBalance, 'input token amount'); | ||||
|                 expect(transfers[0].amountOutMin).to.bignumber.eq(opts.amount, 'output token amount'); | ||||
|                 expect(transfers[0].deadline).to.bignumber.eq(blocktime, 'deadline'); | ||||
|             }); | ||||
|  | ||||
|             it('sets allowance for "from" token', async () => { | ||||
|                 const { logs } = await transferFromAsync(); | ||||
|                 const approvals = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove); | ||||
|                 const routerAddress = await testContract.getRouterAddress().callAsync(); | ||||
|                 expect(approvals.length).to.eq(1); | ||||
|                 expect(approvals[0].spender).to.eq(routerAddress); | ||||
|                 expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256); | ||||
|             }); | ||||
|  | ||||
|             it('sets allowance for "from" token on subsequent calls', async () => { | ||||
|                 const { opts } = await transferFromAsync(); | ||||
|                 const { logs } = await transferFromAsync(opts); | ||||
|                 const approvals = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove); | ||||
|                 const routerAddress = await testContract.getRouterAddress().callAsync(); | ||||
|                 expect(approvals.length).to.eq(1); | ||||
|                 expect(approvals[0].spender).to.eq(routerAddress); | ||||
|                 expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256); | ||||
|             }); | ||||
|  | ||||
|             it('fails if the router fails', async () => { | ||||
|                 const revertReason = 'FOOBAR'; | ||||
|                 const tx = transferFromAsync({ | ||||
|                     routerRevertReason: revertReason, | ||||
|                 }); | ||||
|                 return expect(tx).to.eventually.be.rejectedWith(revertReason); | ||||
|             }); | ||||
|         }); | ||||
|         describe('token -> token -> token', async () => { | ||||
|             it('calls UniswapV2Router01.swapExactTokensForTokens()', async () => { | ||||
|                 const { opts, result, logs, blocktime } = await transferFromAsync({ | ||||
|                     tokenAddressesPath: Array(3).fill(constants.NULL_ADDRESS), | ||||
|                 }); | ||||
|                 expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id'); | ||||
|                 const transfers = filterLogsToArguments<SwapExactTokensForTokensArgs>( | ||||
|                     logs, | ||||
|                     ContractEvents.SwapExactTokensForTokensInput, | ||||
|                 ); | ||||
|  | ||||
|                 expect(transfers.length).to.eq(1); | ||||
|                 expect(transfers[0].toTokenAddress).to.eq( | ||||
|                     opts.tokenAddressesPath[opts.tokenAddressesPath.length - 1], | ||||
|                     'output token address', | ||||
|                 ); | ||||
|                 expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address'); | ||||
|                 expect(transfers[0].amountIn).to.bignumber.eq(opts.fromTokenBalance, 'input token amount'); | ||||
|                 expect(transfers[0].amountOutMin).to.bignumber.eq(opts.amount, 'output token amount'); | ||||
|                 expect(transfers[0].deadline).to.bignumber.eq(blocktime, 'deadline'); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -3,8 +3,14 @@ | ||||
|  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
| export * from '../test/generated-wrappers/balancer_bridge'; | ||||
| export * from '../test/generated-wrappers/bancor_bridge'; | ||||
| export * from '../test/generated-wrappers/chai_bridge'; | ||||
| export * from '../test/generated-wrappers/cream_bridge'; | ||||
| export * from '../test/generated-wrappers/crypto_com_bridge'; | ||||
| export * from '../test/generated-wrappers/curve_bridge'; | ||||
| export * from '../test/generated-wrappers/d_o_d_o_bridge'; | ||||
| export * from '../test/generated-wrappers/dex_forwarder_bridge'; | ||||
| export * from '../test/generated-wrappers/dydx_bridge'; | ||||
| export * from '../test/generated-wrappers/erc1155_proxy'; | ||||
| export * from '../test/generated-wrappers/erc20_bridge_proxy'; | ||||
| @@ -15,26 +21,44 @@ export * from '../test/generated-wrappers/i_asset_data'; | ||||
| export * from '../test/generated-wrappers/i_asset_proxy'; | ||||
| export * from '../test/generated-wrappers/i_asset_proxy_dispatcher'; | ||||
| export * from '../test/generated-wrappers/i_authorizable'; | ||||
| export * from '../test/generated-wrappers/i_balancer_pool'; | ||||
| export * from '../test/generated-wrappers/i_bancor_network'; | ||||
| export * from '../test/generated-wrappers/i_chai'; | ||||
| export * from '../test/generated-wrappers/i_curve'; | ||||
| export * from '../test/generated-wrappers/i_dydx'; | ||||
| export * from '../test/generated-wrappers/i_dydx_bridge'; | ||||
| export * from '../test/generated-wrappers/i_erc20_bridge'; | ||||
| export * from '../test/generated-wrappers/i_eth2_dai'; | ||||
| export * from '../test/generated-wrappers/i_gas_token'; | ||||
| export * from '../test/generated-wrappers/i_kyber_network_proxy'; | ||||
| export * from '../test/generated-wrappers/i_m_stable'; | ||||
| export * from '../test/generated-wrappers/i_mooniswap'; | ||||
| export * from '../test/generated-wrappers/i_shell'; | ||||
| export * from '../test/generated-wrappers/i_uniswap_exchange'; | ||||
| export * from '../test/generated-wrappers/i_uniswap_exchange_factory'; | ||||
| export * from '../test/generated-wrappers/i_uniswap_v2_router01'; | ||||
| export * from '../test/generated-wrappers/kyber_bridge'; | ||||
| export * from '../test/generated-wrappers/m_stable_bridge'; | ||||
| export * from '../test/generated-wrappers/mixin_asset_proxy_dispatcher'; | ||||
| export * from '../test/generated-wrappers/mixin_authorizable'; | ||||
| export * from '../test/generated-wrappers/mixin_gas_token'; | ||||
| export * from '../test/generated-wrappers/mooniswap_bridge'; | ||||
| export * from '../test/generated-wrappers/multi_asset_proxy'; | ||||
| export * from '../test/generated-wrappers/ownable'; | ||||
| export * from '../test/generated-wrappers/shell_bridge'; | ||||
| export * from '../test/generated-wrappers/snow_swap_bridge'; | ||||
| export * from '../test/generated-wrappers/static_call_proxy'; | ||||
| export * from '../test/generated-wrappers/sushi_swap_bridge'; | ||||
| export * from '../test/generated-wrappers/swerve_bridge'; | ||||
| export * from '../test/generated-wrappers/test_bancor_bridge'; | ||||
| export * from '../test/generated-wrappers/test_chai_bridge'; | ||||
| export * from '../test/generated-wrappers/test_dex_forwarder_bridge'; | ||||
| export * from '../test/generated-wrappers/test_dydx_bridge'; | ||||
| export * from '../test/generated-wrappers/test_erc20_bridge'; | ||||
| export * from '../test/generated-wrappers/test_eth2_dai_bridge'; | ||||
| export * from '../test/generated-wrappers/test_kyber_bridge'; | ||||
| export * from '../test/generated-wrappers/test_static_call_target'; | ||||
| export * from '../test/generated-wrappers/test_uniswap_bridge'; | ||||
| export * from '../test/generated-wrappers/test_uniswap_v2_bridge'; | ||||
| export * from '../test/generated-wrappers/uniswap_bridge'; | ||||
| export * from '../test/generated-wrappers/uniswap_v2_bridge'; | ||||
|   | ||||
| @@ -3,8 +3,14 @@ | ||||
|     "compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true }, | ||||
|     "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"], | ||||
|     "files": [ | ||||
|         "generated-artifacts/BalancerBridge.json", | ||||
|         "generated-artifacts/BancorBridge.json", | ||||
|         "generated-artifacts/ChaiBridge.json", | ||||
|         "generated-artifacts/CreamBridge.json", | ||||
|         "generated-artifacts/CryptoComBridge.json", | ||||
|         "generated-artifacts/CurveBridge.json", | ||||
|         "generated-artifacts/DODOBridge.json", | ||||
|         "generated-artifacts/DexForwarderBridge.json", | ||||
|         "generated-artifacts/DydxBridge.json", | ||||
|         "generated-artifacts/ERC1155Proxy.json", | ||||
|         "generated-artifacts/ERC20BridgeProxy.json", | ||||
| @@ -15,31 +21,55 @@ | ||||
|         "generated-artifacts/IAssetProxy.json", | ||||
|         "generated-artifacts/IAssetProxyDispatcher.json", | ||||
|         "generated-artifacts/IAuthorizable.json", | ||||
|         "generated-artifacts/IBalancerPool.json", | ||||
|         "generated-artifacts/IBancorNetwork.json", | ||||
|         "generated-artifacts/IChai.json", | ||||
|         "generated-artifacts/ICurve.json", | ||||
|         "generated-artifacts/IDydx.json", | ||||
|         "generated-artifacts/IDydxBridge.json", | ||||
|         "generated-artifacts/IERC20Bridge.json", | ||||
|         "generated-artifacts/IEth2Dai.json", | ||||
|         "generated-artifacts/IGasToken.json", | ||||
|         "generated-artifacts/IKyberNetworkProxy.json", | ||||
|         "generated-artifacts/IMStable.json", | ||||
|         "generated-artifacts/IMooniswap.json", | ||||
|         "generated-artifacts/IShell.json", | ||||
|         "generated-artifacts/IUniswapExchange.json", | ||||
|         "generated-artifacts/IUniswapExchangeFactory.json", | ||||
|         "generated-artifacts/IUniswapV2Router01.json", | ||||
|         "generated-artifacts/KyberBridge.json", | ||||
|         "generated-artifacts/MStableBridge.json", | ||||
|         "generated-artifacts/MixinAssetProxyDispatcher.json", | ||||
|         "generated-artifacts/MixinAuthorizable.json", | ||||
|         "generated-artifacts/MixinGasToken.json", | ||||
|         "generated-artifacts/MooniswapBridge.json", | ||||
|         "generated-artifacts/MultiAssetProxy.json", | ||||
|         "generated-artifacts/Ownable.json", | ||||
|         "generated-artifacts/ShellBridge.json", | ||||
|         "generated-artifacts/SnowSwapBridge.json", | ||||
|         "generated-artifacts/StaticCallProxy.json", | ||||
|         "generated-artifacts/SushiSwapBridge.json", | ||||
|         "generated-artifacts/SwerveBridge.json", | ||||
|         "generated-artifacts/TestBancorBridge.json", | ||||
|         "generated-artifacts/TestChaiBridge.json", | ||||
|         "generated-artifacts/TestDexForwarderBridge.json", | ||||
|         "generated-artifacts/TestDydxBridge.json", | ||||
|         "generated-artifacts/TestERC20Bridge.json", | ||||
|         "generated-artifacts/TestEth2DaiBridge.json", | ||||
|         "generated-artifacts/TestKyberBridge.json", | ||||
|         "generated-artifacts/TestStaticCallTarget.json", | ||||
|         "generated-artifacts/TestUniswapBridge.json", | ||||
|         "generated-artifacts/TestUniswapV2Bridge.json", | ||||
|         "generated-artifacts/UniswapBridge.json", | ||||
|         "generated-artifacts/UniswapV2Bridge.json", | ||||
|         "test/generated-artifacts/BalancerBridge.json", | ||||
|         "test/generated-artifacts/BancorBridge.json", | ||||
|         "test/generated-artifacts/ChaiBridge.json", | ||||
|         "test/generated-artifacts/CreamBridge.json", | ||||
|         "test/generated-artifacts/CryptoComBridge.json", | ||||
|         "test/generated-artifacts/CurveBridge.json", | ||||
|         "test/generated-artifacts/DODOBridge.json", | ||||
|         "test/generated-artifacts/DexForwarderBridge.json", | ||||
|         "test/generated-artifacts/DydxBridge.json", | ||||
|         "test/generated-artifacts/ERC1155Proxy.json", | ||||
|         "test/generated-artifacts/ERC20BridgeProxy.json", | ||||
| @@ -50,29 +80,47 @@ | ||||
|         "test/generated-artifacts/IAssetProxy.json", | ||||
|         "test/generated-artifacts/IAssetProxyDispatcher.json", | ||||
|         "test/generated-artifacts/IAuthorizable.json", | ||||
|         "test/generated-artifacts/IBalancerPool.json", | ||||
|         "test/generated-artifacts/IBancorNetwork.json", | ||||
|         "test/generated-artifacts/IChai.json", | ||||
|         "test/generated-artifacts/ICurve.json", | ||||
|         "test/generated-artifacts/IDydx.json", | ||||
|         "test/generated-artifacts/IDydxBridge.json", | ||||
|         "test/generated-artifacts/IERC20Bridge.json", | ||||
|         "test/generated-artifacts/IEth2Dai.json", | ||||
|         "test/generated-artifacts/IGasToken.json", | ||||
|         "test/generated-artifacts/IKyberNetworkProxy.json", | ||||
|         "test/generated-artifacts/IMStable.json", | ||||
|         "test/generated-artifacts/IMooniswap.json", | ||||
|         "test/generated-artifacts/IShell.json", | ||||
|         "test/generated-artifacts/IUniswapExchange.json", | ||||
|         "test/generated-artifacts/IUniswapExchangeFactory.json", | ||||
|         "test/generated-artifacts/IUniswapV2Router01.json", | ||||
|         "test/generated-artifacts/KyberBridge.json", | ||||
|         "test/generated-artifacts/MStableBridge.json", | ||||
|         "test/generated-artifacts/MixinAssetProxyDispatcher.json", | ||||
|         "test/generated-artifacts/MixinAuthorizable.json", | ||||
|         "test/generated-artifacts/MixinGasToken.json", | ||||
|         "test/generated-artifacts/MooniswapBridge.json", | ||||
|         "test/generated-artifacts/MultiAssetProxy.json", | ||||
|         "test/generated-artifacts/Ownable.json", | ||||
|         "test/generated-artifacts/ShellBridge.json", | ||||
|         "test/generated-artifacts/SnowSwapBridge.json", | ||||
|         "test/generated-artifacts/StaticCallProxy.json", | ||||
|         "test/generated-artifacts/SushiSwapBridge.json", | ||||
|         "test/generated-artifacts/SwerveBridge.json", | ||||
|         "test/generated-artifacts/TestBancorBridge.json", | ||||
|         "test/generated-artifacts/TestChaiBridge.json", | ||||
|         "test/generated-artifacts/TestDexForwarderBridge.json", | ||||
|         "test/generated-artifacts/TestDydxBridge.json", | ||||
|         "test/generated-artifacts/TestERC20Bridge.json", | ||||
|         "test/generated-artifacts/TestEth2DaiBridge.json", | ||||
|         "test/generated-artifacts/TestKyberBridge.json", | ||||
|         "test/generated-artifacts/TestStaticCallTarget.json", | ||||
|         "test/generated-artifacts/TestUniswapBridge.json", | ||||
|         "test/generated-artifacts/UniswapBridge.json" | ||||
|         "test/generated-artifacts/TestUniswapV2Bridge.json", | ||||
|         "test/generated-artifacts/UniswapBridge.json", | ||||
|         "test/generated-artifacts/UniswapV2Bridge.json" | ||||
|     ], | ||||
|     "exclude": ["./deploy/solc/solc_bin"] | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,176 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1611648096, | ||||
|         "version": "1.1.23", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1610510890, | ||||
|         "version": "1.1.22", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1609802516, | ||||
|         "version": "1.1.21", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608692071, | ||||
|         "version": "1.1.20", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608245516, | ||||
|         "version": "1.1.19", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608105788, | ||||
|         "version": "1.1.18", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607485227, | ||||
|         "version": "1.1.17", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607381756, | ||||
|         "version": "1.1.16", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1606961263, | ||||
|         "version": "1.1.15", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605763885, | ||||
|         "version": "1.1.14", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605302002, | ||||
|         "version": "1.1.13", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604385937, | ||||
|         "version": "1.1.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604376968, | ||||
|         "version": "1.1.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604355662, | ||||
|         "version": "1.1.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603851023, | ||||
|         "version": "1.1.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603833198, | ||||
|         "version": "1.1.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603265572, | ||||
|         "version": "1.1.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1594788383, | ||||
|         "version": "1.1.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.1.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Fix broken tests.", | ||||
|                 "pr": 2591 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1592969527 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1583220306, | ||||
|         "version": "1.1.4", | ||||
|   | ||||
| @@ -5,6 +5,82 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.1.23 - _January 26, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.22 - _January 13, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.21 - _January 4, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.20 - _December 23, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.19 - _December 17, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.18 - _December 16, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.17 - _December 9, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.16 - _December 7, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.15 - _December 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.14 - _November 19, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.13 - _November 13, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.12 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.11 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.10 - _November 2, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.9 - _October 28, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.8 - _October 27, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.7 - _October 21, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.6 - _July 15, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.5 - _June 24, 2020_ | ||||
|  | ||||
|     * Fix broken tests. (#2591) | ||||
|  | ||||
| ## v1.1.4 - _March 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-broker", | ||||
|     "version": "1.1.4", | ||||
|     "version": "1.1.23", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -43,31 +43,31 @@ | ||||
|     }, | ||||
|     "repository": { | ||||
|         "type": "git", | ||||
|         "url": "https://github.com/0xProject/0x-monorepo.git" | ||||
|         "url": "https://github.com/0xProject/protocol.git" | ||||
|     }, | ||||
|     "license": "Apache-2.0", | ||||
|     "bugs": { | ||||
|         "url": "https://github.com/0xProject/0x-monorepo/issues" | ||||
|         "url": "https://github.com/0xProject/protocol/issues" | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md", | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.2.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.2.5", | ||||
|         "@0x/contracts-erc20": "^3.1.5", | ||||
|         "@0x/contracts-erc721": "^3.1.5", | ||||
|         "@0x/contracts-exchange": "^3.2.5", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.5", | ||||
|         "@0x/contracts-gen": "^2.0.8", | ||||
|         "@0x/contracts-test-utils": "^5.3.2", | ||||
|         "@0x/contracts-utils": "^4.4.3", | ||||
|         "@0x/sol-compiler": "^4.0.8", | ||||
|         "@0x/ts-doc-gen": "^0.0.22", | ||||
|         "@0x/tslint-config": "^4.0.0", | ||||
|         "@0x/types": "^3.1.2", | ||||
|         "@0x/web3-wrapper": "^7.0.7", | ||||
|         "@0x/abi-gen": "^5.4.19", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.5", | ||||
|         "@0x/contracts-erc20": "^3.3.2", | ||||
|         "@0x/contracts-erc721": "^3.1.23", | ||||
|         "@0x/contracts-exchange": "^3.2.24", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.23", | ||||
|         "@0x/contracts-gen": "^2.0.30", | ||||
|         "@0x/contracts-test-utils": "^5.3.20", | ||||
|         "@0x/contracts-utils": "^4.7.2", | ||||
|         "@0x/sol-compiler": "^4.5.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "@types/node": "12.12.54", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
| @@ -80,17 +80,18 @@ | ||||
|         "solhint": "^1.4.1", | ||||
|         "truffle": "^5.0.32", | ||||
|         "tslint": "5.11.0", | ||||
|         "typedoc": "^0.15.0", | ||||
|         "typedoc": "~0.16.11", | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.1", | ||||
|         "@0x/order-utils": "^10.2.4", | ||||
|         "@0x/typescript-typings": "^5.0.2", | ||||
|         "@0x/utils": "^5.4.1", | ||||
|         "ethereum-types": "^3.1.0" | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/order-utils": "^10.4.15", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "ethereum-types": "^3.4.0" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|     } | ||||
|     }, | ||||
|     "gitHead": "4f91bfd907996b2f4dd383778b50c479c2602b56" | ||||
| } | ||||
|   | ||||
| @@ -44,13 +44,13 @@ blockchainTests.resets('GodsUnchainedValidator unit tests', env => { | ||||
|             const tokenId = getRandomInteger(0, constants.MAX_UINT256); | ||||
|             await godsUnchained.setTokenProperties(tokenId, proto.plus(1), quality).awaitTransactionSuccessAsync(); | ||||
|             const tx = validator.checkBrokerAsset(tokenId, propertyData).callAsync(); | ||||
|             expect(tx).to.revertWith('PROTO_MISMATCH'); | ||||
|             expect(tx).to.revertWith('GodsUnchainedValidator/PROTO_MISMATCH'); | ||||
|         }); | ||||
|         it("reverts if assetData quality doesn't match proeprtyData", async () => { | ||||
|             const tokenId = getRandomInteger(0, constants.MAX_UINT256); | ||||
|             await godsUnchained.setTokenProperties(tokenId, proto, quality.plus(1)).awaitTransactionSuccessAsync(); | ||||
|             const tx = validator.checkBrokerAsset(tokenId, propertyData).callAsync(); | ||||
|             expect(tx).to.revertWith('QUALITY_MISMATCH'); | ||||
|             expect(tx).to.revertWith('GodsUnchainedValidator/QUALITY_MISMATCH'); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
|   | ||||
| @@ -1,4 +1,175 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1611648096, | ||||
|         "version": "3.1.24", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1610510890, | ||||
|         "version": "3.1.23", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1609802516, | ||||
|         "version": "3.1.22", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608692071, | ||||
|         "version": "3.1.21", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608245516, | ||||
|         "version": "3.1.20", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608105788, | ||||
|         "version": "3.1.19", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607485227, | ||||
|         "version": "3.1.18", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607381756, | ||||
|         "version": "3.1.17", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1606961263, | ||||
|         "version": "3.1.16", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605763885, | ||||
|         "version": "3.1.15", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605302002, | ||||
|         "version": "3.1.14", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604385937, | ||||
|         "version": "3.1.13", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604376968, | ||||
|         "version": "3.1.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604355662, | ||||
|         "version": "3.1.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603851023, | ||||
|         "version": "3.1.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603833198, | ||||
|         "version": "3.1.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603265572, | ||||
|         "version": "3.1.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1594788383, | ||||
|         "version": "3.1.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1592969527, | ||||
|         "version": "3.1.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1583220306, | ||||
|         "version": "3.1.5", | ||||
|   | ||||
| @@ -5,6 +5,82 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.1.24 - _January 26, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.23 - _January 13, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.22 - _January 4, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.21 - _December 23, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.20 - _December 17, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.19 - _December 16, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.18 - _December 9, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.17 - _December 7, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.16 - _December 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.15 - _November 19, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.14 - _November 13, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.13 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.12 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.11 - _November 2, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.10 - _October 28, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.9 - _October 27, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.8 - _October 21, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.7 - _July 15, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.6 - _June 24, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.5 - _March 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-coordinator", | ||||
|     "version": "3.1.5", | ||||
|     "version": "3.1.24", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -44,30 +44,28 @@ | ||||
|     }, | ||||
|     "repository": { | ||||
|         "type": "git", | ||||
|         "url": "https://github.com/0xProject/0x-monorepo.git" | ||||
|         "url": "https://github.com/0xProject/protocol.git" | ||||
|     }, | ||||
|     "license": "Apache-2.0", | ||||
|     "bugs": { | ||||
|         "url": "https://github.com/0xProject/0x-monorepo/issues" | ||||
|         "url": "https://github.com/0xProject/protocol/issues" | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md", | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.2.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.2.5", | ||||
|         "@0x/contracts-dev-utils": "^1.3.3", | ||||
|         "@0x/contracts-erc20": "^3.1.5", | ||||
|         "@0x/contracts-exchange": "^3.2.5", | ||||
|         "@0x/contracts-gen": "^2.0.8", | ||||
|         "@0x/contracts-test-utils": "^5.3.2", | ||||
|         "@0x/dev-utils": "^3.2.1", | ||||
|         "@0x/order-utils": "^10.2.4", | ||||
|         "@0x/sol-compiler": "^4.0.8", | ||||
|         "@0x/ts-doc-gen": "^0.0.22", | ||||
|         "@0x/tslint-config": "^4.0.0", | ||||
|         "@0x/web3-wrapper": "^7.0.7", | ||||
|         "@0x/abi-gen": "^5.4.19", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.5", | ||||
|         "@0x/contracts-dev-utils": "^1.3.22", | ||||
|         "@0x/contracts-erc20": "^3.3.2", | ||||
|         "@0x/contracts-gen": "^2.0.30", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/order-utils": "^10.4.15", | ||||
|         "@0x/sol-compiler": "^4.5.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "@types/node": "12.12.54", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
| @@ -80,22 +78,25 @@ | ||||
|         "solhint": "^1.4.1", | ||||
|         "truffle": "^5.0.32", | ||||
|         "tslint": "5.11.0", | ||||
|         "typedoc": "^0.15.0", | ||||
|         "typedoc": "~0.16.11", | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/assert": "^3.0.7", | ||||
|         "@0x/base-contract": "^6.2.1", | ||||
|         "@0x/contract-addresses": "^4.9.0", | ||||
|         "@0x/contracts-utils": "^4.4.3", | ||||
|         "@0x/json-schemas": "^5.0.7", | ||||
|         "@0x/types": "^3.1.2", | ||||
|         "@0x/typescript-typings": "^5.0.2", | ||||
|         "@0x/utils": "^5.4.1", | ||||
|         "ethereum-types": "^3.1.0", | ||||
|         "@0x/assert": "^3.0.21", | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contract-addresses": "^5.9.0", | ||||
|         "@0x/contracts-exchange": "^3.2.24", | ||||
|         "@0x/contracts-test-utils": "^5.3.20", | ||||
|         "@0x/contracts-utils": "^4.7.2", | ||||
|         "@0x/json-schemas": "^5.4.1", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "http-status-codes": "^1.3.2" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|     } | ||||
|     }, | ||||
|     "gitHead": "4f91bfd907996b2f4dd383778b50c479c2602b56" | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,175 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1611648096, | ||||
|         "version": "1.3.22", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1610510890, | ||||
|         "version": "1.3.21", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1609802516, | ||||
|         "version": "1.3.20", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608692071, | ||||
|         "version": "1.3.19", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608245516, | ||||
|         "version": "1.3.18", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608105788, | ||||
|         "version": "1.3.17", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607485227, | ||||
|         "version": "1.3.16", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607381756, | ||||
|         "version": "1.3.15", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1606961263, | ||||
|         "version": "1.3.14", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605763885, | ||||
|         "version": "1.3.13", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605302002, | ||||
|         "version": "1.3.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604385937, | ||||
|         "version": "1.3.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604376968, | ||||
|         "version": "1.3.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604355662, | ||||
|         "version": "1.3.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603851023, | ||||
|         "version": "1.3.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603833198, | ||||
|         "version": "1.3.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603265572, | ||||
|         "version": "1.3.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1594788383, | ||||
|         "version": "1.3.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1592969527, | ||||
|         "version": "1.3.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1583220306, | ||||
|         "version": "1.3.3", | ||||
|   | ||||
| @@ -5,6 +5,82 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.3.22 - _January 26, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.21 - _January 13, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.20 - _January 4, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.19 - _December 23, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.18 - _December 17, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.17 - _December 16, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.16 - _December 9, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.15 - _December 7, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.14 - _December 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.13 - _November 19, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.12 - _November 13, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.11 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.10 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.9 - _November 2, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.8 - _October 28, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.7 - _October 27, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.6 - _October 21, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.5 - _July 15, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.4 - _June 24, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.3 - _March 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-dev-utils", | ||||
|     "version": "1.3.3", | ||||
|     "version": "1.3.22", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -33,40 +33,41 @@ | ||||
|     }, | ||||
|     "repository": { | ||||
|         "type": "git", | ||||
|         "url": "https://github.com/0xProject/0x-monorepo.git" | ||||
|         "url": "https://github.com/0xProject/protocol.git" | ||||
|     }, | ||||
|     "license": "Apache-2.0", | ||||
|     "bugs": { | ||||
|         "url": "https://github.com/0xProject/0x-monorepo/issues" | ||||
|         "url": "https://github.com/0xProject/protocol/issues" | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/dev-utils/README.md", | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/dev-utils", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.2.2", | ||||
|         "@0x/assert": "^3.0.7", | ||||
|         "@0x/contracts-asset-proxy": "^3.2.5", | ||||
|         "@0x/contracts-erc20": "^3.1.5", | ||||
|         "@0x/contracts-gen": "^2.0.8", | ||||
|         "@0x/contracts-test-utils": "^5.3.2", | ||||
|         "@0x/sol-compiler": "^4.0.8", | ||||
|         "@0x/ts-doc-gen": "^0.0.22", | ||||
|         "@0x/tslint-config": "^4.0.0", | ||||
|         "@0x/types": "^3.1.2", | ||||
|         "@0x/utils": "^5.4.1", | ||||
|         "@types/node": "*", | ||||
|         "ethereum-types": "^3.1.0", | ||||
|         "@0x/abi-gen": "^5.4.19", | ||||
|         "@0x/assert": "^3.0.21", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.5", | ||||
|         "@0x/contracts-erc20": "^3.3.2", | ||||
|         "@0x/contracts-gen": "^2.0.30", | ||||
|         "@0x/contracts-test-utils": "^5.3.20", | ||||
|         "@0x/sol-compiler": "^4.5.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethers": "~4.0.4", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
|         "solhint": "^1.4.1", | ||||
|         "truffle": "^5.0.32", | ||||
|         "tslint": "5.11.0", | ||||
|         "typedoc": "^0.15.0", | ||||
|         "typedoc": "~0.16.11", | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.1" | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@types/node": "12.12.54" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|     } | ||||
|     }, | ||||
|     "gitHead": "4f91bfd907996b2f4dd383778b50c479c2602b56" | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,166 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1611648096, | ||||
|         "version": "2.1.23", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1610510890, | ||||
|         "version": "2.1.22", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1609802516, | ||||
|         "version": "2.1.21", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608692071, | ||||
|         "version": "2.1.20", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608245516, | ||||
|         "version": "2.1.19", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607485227, | ||||
|         "version": "2.1.18", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607381756, | ||||
|         "version": "2.1.17", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1606961263, | ||||
|         "version": "2.1.16", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605763885, | ||||
|         "version": "2.1.15", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605302002, | ||||
|         "version": "2.1.14", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604385937, | ||||
|         "version": "2.1.13", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604376968, | ||||
|         "version": "2.1.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604355662, | ||||
|         "version": "2.1.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603851023, | ||||
|         "version": "2.1.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603833198, | ||||
|         "version": "2.1.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603265572, | ||||
|         "version": "2.1.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1594788383, | ||||
|         "version": "2.1.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1592969527, | ||||
|         "version": "2.1.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1583220306, | ||||
|         "version": "2.1.5", | ||||
|   | ||||
| @@ -5,6 +5,78 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v2.1.23 - _January 26, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.22 - _January 13, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.21 - _January 4, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.20 - _December 23, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.19 - _December 17, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.18 - _December 9, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.17 - _December 7, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.16 - _December 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.15 - _November 19, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.14 - _November 13, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.13 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.12 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.11 - _November 2, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.10 - _October 28, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.9 - _October 27, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.8 - _October 21, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.7 - _July 15, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.6 - _June 24, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.5 - _March 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc1155", | ||||
|     "version": "2.1.5", | ||||
|     "version": "2.1.23", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -44,31 +44,31 @@ | ||||
|     }, | ||||
|     "repository": { | ||||
|         "type": "git", | ||||
|         "url": "https://github.com/0xProject/0x-monorepo.git" | ||||
|         "url": "https://github.com/0xProject/protocol.git" | ||||
|     }, | ||||
|     "license": "Apache-2.0", | ||||
|     "bugs": { | ||||
|         "url": "https://github.com/0xProject/0x-monorepo/issues" | ||||
|         "url": "https://github.com/0xProject/protocol/issues" | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md", | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.2.2", | ||||
|         "@0x/contracts-gen": "^2.0.8", | ||||
|         "@0x/contracts-utils": "^4.4.3", | ||||
|         "@0x/dev-utils": "^3.2.1", | ||||
|         "@0x/sol-compiler": "^4.0.8", | ||||
|         "@0x/ts-doc-gen": "^0.0.22", | ||||
|         "@0x/tslint-config": "^4.0.0", | ||||
|         "@0x/types": "^3.1.2", | ||||
|         "@0x/typescript-typings": "^5.0.2", | ||||
|         "@0x/abi-gen": "^5.4.19", | ||||
|         "@0x/contracts-gen": "^2.0.30", | ||||
|         "@0x/contracts-utils": "^4.7.2", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.5.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "@types/node": "12.12.54", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereum-types": "^3.1.0", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
| @@ -76,17 +76,18 @@ | ||||
|         "solhint": "^1.4.1", | ||||
|         "truffle": "^5.0.32", | ||||
|         "tslint": "5.11.0", | ||||
|         "typedoc": "^0.15.0", | ||||
|         "typedoc": "~0.16.11", | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.1", | ||||
|         "@0x/contracts-test-utils": "^5.3.2", | ||||
|         "@0x/utils": "^5.4.1", | ||||
|         "@0x/web3-wrapper": "^7.0.7", | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contracts-test-utils": "^5.3.20", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|     } | ||||
|     }, | ||||
|     "gitHead": "4f91bfd907996b2f4dd383778b50c479c2602b56" | ||||
| } | ||||
|   | ||||
| @@ -1,157 +0,0 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1583220306, | ||||
|         "version": "1.5.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.5.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add generic liquidity provider sampling", | ||||
|                 "pr": 2487 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Use liquidity provider registry in sampler", | ||||
|                 "pr": 2499 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1582837861 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1582677073, | ||||
|         "version": "1.4.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1582623685, | ||||
|         "version": "1.4.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.4.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Added Curve contract sampling", | ||||
|                 "pr": 2483 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1581748629 | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.3.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Catch reverts to `DevUtils` calls", | ||||
|                 "pr": 2476 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Remove wrapper functions and introduce `batchCall()`", | ||||
|                 "pr": 2477 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1581204851 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1580988106, | ||||
|         "version": "1.2.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.2.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Make source IDs static on all networks, not inherited from `DeploymentConstants`.", | ||||
|                 "pr": 2459 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1580811564 | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.1.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add batch functions to query quotes", | ||||
|                 "pr": 2427 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Early exit if a DEX sample fails", | ||||
|                 "pr": 2427 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1579682890 | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.0.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add gas limits to external quote calls.", | ||||
|                 "pr": 2405 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1578272714 | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.0.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Do not query empty/unsigned orders. Swallow revets on DEX quotes.", | ||||
|                 "pr": 2395 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1576540892 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1575931811, | ||||
|         "version": "1.0.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.0.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Created package.", | ||||
|                 "pr": 2344 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1575296764 | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.0.0-beta.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1575290197 | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.0.0-beta.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Created package.", | ||||
|                 "pr": 2344 | ||||
|             } | ||||
|         ] | ||||
|     } | ||||
| ] | ||||
| @@ -1,69 +0,0 @@ | ||||
| <!-- | ||||
| changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly. | ||||
| Edit the package's CHANGELOG.json file only. | ||||
| --> | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.5.1 - _March 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.5.0 - _February 27, 2020_ | ||||
|  | ||||
|     * Add generic liquidity provider sampling (#2487) | ||||
|     * Use liquidity provider registry in sampler (#2499) | ||||
|  | ||||
| ## v1.4.2 - _February 26, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.4.1 - _February 25, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.4.0 - _February 15, 2020_ | ||||
|  | ||||
|     * Added Curve contract sampling (#2483) | ||||
|  | ||||
| ## v1.3.0 - _February 8, 2020_ | ||||
|  | ||||
|     * Catch reverts to `DevUtils` calls (#2476) | ||||
|     * Remove wrapper functions and introduce `batchCall()` (#2477) | ||||
|  | ||||
| ## v1.2.1 - _February 6, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.2.0 - _February 4, 2020_ | ||||
|  | ||||
|     * Make source IDs static on all networks, not inherited from `DeploymentConstants`. (#2459) | ||||
|  | ||||
| ## v1.1.0 - _January 22, 2020_ | ||||
|  | ||||
|     * Add batch functions to query quotes (#2427) | ||||
|     * Early exit if a DEX sample fails (#2427) | ||||
|  | ||||
| ## v1.0.3 - _January 6, 2020_ | ||||
|  | ||||
|     * Add gas limits to external quote calls. (#2405) | ||||
|  | ||||
| ## v1.0.2 - _December 17, 2019_ | ||||
|  | ||||
|     * Do not query empty/unsigned orders. Swallow revets on DEX quotes. (#2395) | ||||
|  | ||||
| ## v1.0.1 - _December 9, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.0.0 - _December 2, 2019_ | ||||
|  | ||||
|     * Created package. (#2344) | ||||
|  | ||||
| ## v1.0.0-beta.2 - _December 2, 2019_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.0.0-beta.1 - _Invalid date_ | ||||
|  | ||||
|     * Created package. (#2344) | ||||
| @@ -1,635 +0,0 @@ | ||||
| /* | ||||
|  | ||||
|   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.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-asset-proxy/contracts/src/interfaces/IUniswapExchangeFactory.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.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/DeploymentConstants.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibBytes.sol"; | ||||
| import "./IDevUtils.sol"; | ||||
| import "./IERC20BridgeSampler.sol"; | ||||
| import "./IEth2Dai.sol"; | ||||
| import "./IKyberNetwork.sol"; | ||||
| import "./IUniswapExchangeQuotes.sol"; | ||||
| import "./ICurve.sol"; | ||||
| import "./ILiquidityProvider.sol"; | ||||
| import "./ILiquidityProviderRegistry.sol"; | ||||
|  | ||||
|  | ||||
| contract ERC20BridgeSampler is | ||||
|     IERC20BridgeSampler, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     /// @dev Gas limit for DevUtils calls. | ||||
|     uint256 constant internal DEV_UTILS_CALL_GAS = 500e3; // 500k | ||||
|     /// @dev Gas limit for Kyber calls. | ||||
|     uint256 constant internal KYBER_CALL_GAS = 1500e3; // 1.5m | ||||
|     /// @dev Gas limit for Uniswap calls. | ||||
|     uint256 constant internal UNISWAP_CALL_GAS = 150e3; // 150k | ||||
|     /// @dev Base gas limit for Eth2Dai calls. | ||||
|     uint256 constant internal ETH2DAI_CALL_GAS = 1000e3; // 1m | ||||
|     /// @dev Base gas limit for Curve calls. Some Curves have multiple tokens | ||||
|     ///      So a reasonable ceil is 150k per token. Biggest Curve has 4 tokens. | ||||
|     uint256 constant internal CURVE_CALL_GAS = 600e3; // 600k | ||||
|     /// @dev Default gas limit for liquidity provider calls. | ||||
|     uint256 constant internal DEFAULT_CALL_GAS = 200e3; // 200k | ||||
|  | ||||
|     /// @dev Call multiple public functions on this contract in a single transaction. | ||||
|     /// @param callDatas ABI-encoded call data for each function call. | ||||
|     /// @return callResults ABI-encoded results data for each call. | ||||
|     function batchCall(bytes[] calldata callDatas) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes[] memory callResults) | ||||
|     { | ||||
|         callResults = new bytes[](callDatas.length); | ||||
|         for (uint256 i = 0; i != callDatas.length; ++i) { | ||||
|             (bool didSucceed, bytes memory resultData) = address(this).staticcall(callDatas[i]); | ||||
|             if (!didSucceed) { | ||||
|                 assembly { revert(add(resultData, 0x20), mload(resultData)) } | ||||
|             } | ||||
|             callResults[i] = resultData; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Queries the fillable taker asset amounts of native orders. | ||||
|     ///      Effectively ignores orders that have empty signatures or | ||||
|     ///      maker/taker asset amounts (returning 0). | ||||
|     /// @param orders Native orders to query. | ||||
|     /// @param orderSignatures Signatures for each respective order in `orders`. | ||||
|     /// @return orderFillableTakerAssetAmounts How much taker asset can be filled | ||||
|     ///         by each order in `orders`. | ||||
|     function getOrderFillableTakerAssetAmounts( | ||||
|         LibOrder.Order[] memory orders, | ||||
|         bytes[] memory orderSignatures | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory orderFillableTakerAssetAmounts) | ||||
|     { | ||||
|         orderFillableTakerAssetAmounts = new uint256[](orders.length); | ||||
|         for (uint256 i = 0; i != orders.length; i++) { | ||||
|             // Ignore orders with no signature or empty maker/taker amounts. | ||||
|             if (orderSignatures[i].length == 0 || | ||||
|                 orders[i].makerAssetAmount == 0 || | ||||
|                 orders[i].takerAssetAmount == 0) { | ||||
|                 orderFillableTakerAssetAmounts[i] = 0; | ||||
|                 continue; | ||||
|             } | ||||
|             // solhint-disable indent | ||||
|             (bool didSucceed, bytes memory resultData) = | ||||
|                 _getDevUtilsAddress() | ||||
|                     .staticcall | ||||
|                     .gas(DEV_UTILS_CALL_GAS) | ||||
|                     (abi.encodeWithSelector( | ||||
|                        IDevUtils(_getDevUtilsAddress()).getOrderRelevantState.selector, | ||||
|                        orders[i], | ||||
|                        orderSignatures[i] | ||||
|                     )); | ||||
|             // solhint-enable indent | ||||
|             if (!didSucceed) { | ||||
|                 orderFillableTakerAssetAmounts[i] = 0; | ||||
|                 continue; | ||||
|             } | ||||
|             ( | ||||
|                 LibOrder.OrderInfo memory orderInfo, | ||||
|                 uint256 fillableTakerAssetAmount, | ||||
|                 bool isValidSignature | ||||
|             ) = abi.decode( | ||||
|                 resultData, | ||||
|                 (LibOrder.OrderInfo, uint256, bool) | ||||
|             ); | ||||
|             // The fillable amount is zero if the order is not fillable or if the | ||||
|             // signature is invalid. | ||||
|             if (orderInfo.orderStatus != LibOrder.OrderStatus.FILLABLE || | ||||
|                 !isValidSignature) { | ||||
|                 orderFillableTakerAssetAmounts[i] = 0; | ||||
|             } else { | ||||
|                 orderFillableTakerAssetAmounts[i] = fillableTakerAssetAmount; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Queries the fillable taker asset amounts of native orders. | ||||
|     ///      Effectively ignores orders that have empty signatures or | ||||
|     /// @param orders Native orders to query. | ||||
|     /// @param orderSignatures Signatures for each respective order in `orders`. | ||||
|     /// @return orderFillableMakerAssetAmounts How much maker asset can be filled | ||||
|     ///         by each order in `orders`. | ||||
|     function getOrderFillableMakerAssetAmounts( | ||||
|         LibOrder.Order[] memory orders, | ||||
|         bytes[] memory orderSignatures | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory orderFillableMakerAssetAmounts) | ||||
|     { | ||||
|         orderFillableMakerAssetAmounts = getOrderFillableTakerAssetAmounts( | ||||
|             orders, | ||||
|             orderSignatures | ||||
|         ); | ||||
|         // `orderFillableMakerAssetAmounts` now holds taker asset amounts, so | ||||
|         // convert them to maker asset amounts. | ||||
|         for (uint256 i = 0; i < orders.length; ++i) { | ||||
|             if (orderFillableMakerAssetAmounts[i] != 0) { | ||||
|                 orderFillableMakerAssetAmounts[i] = LibMath.getPartialAmountCeil( | ||||
|                     orderFillableMakerAssetAmounts[i], | ||||
|                     orders[i].takerAssetAmount, | ||||
|                     orders[i].makerAssetAmount | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Sample sell quotes from Kyber. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromKyberNetwork( | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] memory takerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts) | ||||
|     { | ||||
|         _assertValidPair(makerToken, takerToken); | ||||
|         address _takerToken = takerToken == _getWethAddress() ? KYBER_ETH_ADDRESS : takerToken; | ||||
|         address _makerToken = makerToken == _getWethAddress() ? KYBER_ETH_ADDRESS : makerToken; | ||||
|         uint256 takerTokenDecimals = _getTokenDecimals(takerToken); | ||||
|         uint256 makerTokenDecimals = _getTokenDecimals(makerToken); | ||||
|         uint256 numSamples = takerTokenAmounts.length; | ||||
|         makerTokenAmounts = new uint256[](numSamples); | ||||
|         for (uint256 i = 0; i < numSamples; i++) { | ||||
|             (bool didSucceed, bytes memory resultData) = | ||||
|                 _getKyberNetworkProxyAddress().staticcall.gas(KYBER_CALL_GAS)( | ||||
|                     abi.encodeWithSelector( | ||||
|                         IKyberNetwork(0).getExpectedRate.selector, | ||||
|                         _takerToken, | ||||
|                         _makerToken, | ||||
|                         takerTokenAmounts[i] | ||||
|                     )); | ||||
|             uint256 rate = 0; | ||||
|             if (didSucceed) { | ||||
|                 rate = abi.decode(resultData, (uint256)); | ||||
|             } else { | ||||
|                 break; | ||||
|             } | ||||
|             makerTokenAmounts[i] = | ||||
|                 rate * | ||||
|                 takerTokenAmounts[i] * | ||||
|                 10 ** makerTokenDecimals / | ||||
|                 10 ** takerTokenDecimals / | ||||
|                 10 ** 18; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Sample sell quotes from Eth2Dai/Oasis. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromEth2Dai( | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] memory takerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts) | ||||
|     { | ||||
|         _assertValidPair(makerToken, takerToken); | ||||
|         uint256 numSamples = takerTokenAmounts.length; | ||||
|         makerTokenAmounts = new uint256[](numSamples); | ||||
|         for (uint256 i = 0; i < numSamples; i++) { | ||||
|             (bool didSucceed, bytes memory resultData) = | ||||
|                 _getEth2DaiAddress().staticcall.gas(ETH2DAI_CALL_GAS)( | ||||
|                     abi.encodeWithSelector( | ||||
|                         IEth2Dai(0).getBuyAmount.selector, | ||||
|                         makerToken, | ||||
|                         takerToken, | ||||
|                         takerTokenAmounts[i] | ||||
|                     )); | ||||
|             uint256 buyAmount = 0; | ||||
|             if (didSucceed) { | ||||
|                 buyAmount = abi.decode(resultData, (uint256)); | ||||
|             } else{ | ||||
|                 break; | ||||
|             } | ||||
|             makerTokenAmounts[i] = buyAmount; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Sample buy quotes from Eth2Dai/Oasis. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Maker token sell amount for each sample. | ||||
|     /// @return takerTokenAmounts Taker amounts sold at each maker token | ||||
|     ///         amount. | ||||
|     function sampleBuysFromEth2Dai( | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] memory makerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory takerTokenAmounts) | ||||
|     { | ||||
|         _assertValidPair(makerToken, takerToken); | ||||
|         uint256 numSamples = makerTokenAmounts.length; | ||||
|         takerTokenAmounts = new uint256[](numSamples); | ||||
|         for (uint256 i = 0; i < numSamples; i++) { | ||||
|             (bool didSucceed, bytes memory resultData) = | ||||
|                 _getEth2DaiAddress().staticcall.gas(ETH2DAI_CALL_GAS)( | ||||
|                     abi.encodeWithSelector( | ||||
|                         IEth2Dai(0).getPayAmount.selector, | ||||
|                         takerToken, | ||||
|                         makerToken, | ||||
|                         makerTokenAmounts[i] | ||||
|                     )); | ||||
|             uint256 sellAmount = 0; | ||||
|             if (didSucceed) { | ||||
|                 sellAmount = abi.decode(resultData, (uint256)); | ||||
|             } else { | ||||
|                 break; | ||||
|             } | ||||
|             takerTokenAmounts[i] = sellAmount; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Sample sell quotes from Uniswap. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromUniswap( | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] memory takerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts) | ||||
|     { | ||||
|         _assertValidPair(makerToken, takerToken); | ||||
|         uint256 numSamples = takerTokenAmounts.length; | ||||
|         makerTokenAmounts = new uint256[](numSamples); | ||||
|         IUniswapExchangeQuotes takerTokenExchange = takerToken == _getWethAddress() ? | ||||
|             IUniswapExchangeQuotes(0) : _getUniswapExchange(takerToken); | ||||
|         IUniswapExchangeQuotes makerTokenExchange = makerToken == _getWethAddress() ? | ||||
|             IUniswapExchangeQuotes(0) : _getUniswapExchange(makerToken); | ||||
|         for (uint256 i = 0; i < numSamples; i++) { | ||||
|             bool didSucceed = true; | ||||
|             if (makerToken == _getWethAddress()) { | ||||
|                 (makerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( | ||||
|                     address(takerTokenExchange), | ||||
|                     takerTokenExchange.getTokenToEthInputPrice.selector, | ||||
|                     takerTokenAmounts[i] | ||||
|                 ); | ||||
|             } else if (takerToken == _getWethAddress()) { | ||||
|                 (makerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( | ||||
|                     address(makerTokenExchange), | ||||
|                     makerTokenExchange.getEthToTokenInputPrice.selector, | ||||
|                     takerTokenAmounts[i] | ||||
|                 ); | ||||
|             } else { | ||||
|                 uint256 ethBought; | ||||
|                 (ethBought, didSucceed) = _callUniswapExchangePriceFunction( | ||||
|                     address(takerTokenExchange), | ||||
|                     takerTokenExchange.getTokenToEthInputPrice.selector, | ||||
|                     takerTokenAmounts[i] | ||||
|                 ); | ||||
|                 if (ethBought != 0) { | ||||
|                     (makerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( | ||||
|                         address(makerTokenExchange), | ||||
|                         makerTokenExchange.getEthToTokenInputPrice.selector, | ||||
|                         ethBought | ||||
|                     ); | ||||
|                 } else { | ||||
|                     makerTokenAmounts[i] = 0; | ||||
|                 } | ||||
|             } | ||||
|             if (!didSucceed) { | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Sample buy quotes from Uniswap. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param makerTokenAmounts Maker token sell amount for each sample. | ||||
|     /// @return takerTokenAmounts Taker amounts sold at each maker token | ||||
|     ///         amount. | ||||
|     function sampleBuysFromUniswap( | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] memory makerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory takerTokenAmounts) | ||||
|     { | ||||
|         _assertValidPair(makerToken, takerToken); | ||||
|         uint256 numSamples = makerTokenAmounts.length; | ||||
|         takerTokenAmounts = new uint256[](numSamples); | ||||
|         IUniswapExchangeQuotes takerTokenExchange = takerToken == _getWethAddress() ? | ||||
|             IUniswapExchangeQuotes(0) : _getUniswapExchange(takerToken); | ||||
|         IUniswapExchangeQuotes makerTokenExchange = makerToken == _getWethAddress() ? | ||||
|             IUniswapExchangeQuotes(0) : _getUniswapExchange(makerToken); | ||||
|         for (uint256 i = 0; i < numSamples; i++) { | ||||
|             bool didSucceed = true; | ||||
|             if (makerToken == _getWethAddress()) { | ||||
|                 (takerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( | ||||
|                     address(takerTokenExchange), | ||||
|                     takerTokenExchange.getTokenToEthOutputPrice.selector, | ||||
|                     makerTokenAmounts[i] | ||||
|                 ); | ||||
|             } else if (takerToken == _getWethAddress()) { | ||||
|                 (takerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( | ||||
|                     address(makerTokenExchange), | ||||
|                     makerTokenExchange.getEthToTokenOutputPrice.selector, | ||||
|                     makerTokenAmounts[i] | ||||
|                 ); | ||||
|             } else { | ||||
|                 uint256 ethSold; | ||||
|                 (ethSold, didSucceed) = _callUniswapExchangePriceFunction( | ||||
|                     address(makerTokenExchange), | ||||
|                     makerTokenExchange.getEthToTokenOutputPrice.selector, | ||||
|                     makerTokenAmounts[i] | ||||
|                 ); | ||||
|                 if (ethSold != 0) { | ||||
|                     (takerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( | ||||
|                         address(takerTokenExchange), | ||||
|                         takerTokenExchange.getTokenToEthOutputPrice.selector, | ||||
|                         ethSold | ||||
|                     ); | ||||
|                 } else { | ||||
|                     takerTokenAmounts[i] = 0; | ||||
|                 } | ||||
|             } | ||||
|             if (!didSucceed) { | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Sample sell quotes from Curve. | ||||
|     /// @param curveAddress Address of the Curve contract. | ||||
|     /// @param fromTokenIdx Index of the taker token (what to sell). | ||||
|     /// @param toTokenIdx Index of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromCurve( | ||||
|         address curveAddress, | ||||
|         int128 fromTokenIdx, | ||||
|         int128 toTokenIdx, | ||||
|         uint256[] memory takerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts) | ||||
|     { | ||||
|         uint256 numSamples = takerTokenAmounts.length; | ||||
|         makerTokenAmounts = new uint256[](numSamples); | ||||
|         for (uint256 i = 0; i < numSamples; i++) { | ||||
|             (bool didSucceed, bytes memory resultData) = | ||||
|                 curveAddress.staticcall.gas(CURVE_CALL_GAS)( | ||||
|                     abi.encodeWithSelector( | ||||
|                         ICurve(0).get_dy_underlying.selector, | ||||
|                         fromTokenIdx, | ||||
|                         toTokenIdx, | ||||
|                         takerTokenAmounts[i] | ||||
|                     )); | ||||
|             uint256 buyAmount = 0; | ||||
|             if (didSucceed) { | ||||
|                 buyAmount = abi.decode(resultData, (uint256)); | ||||
|             } else { | ||||
|                 break; | ||||
|             } | ||||
|             makerTokenAmounts[i] = buyAmount; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Sample sell quotes from an arbitrary on-chain liquidity provider. | ||||
|     /// @param registryAddress Address of the liquidity provider registry contract. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromLiquidityProviderRegistry( | ||||
|         address registryAddress, | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] memory takerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts) | ||||
|     { | ||||
|         // Initialize array of maker token amounts. | ||||
|         uint256 numSamples = takerTokenAmounts.length; | ||||
|         makerTokenAmounts = new uint256[](numSamples); | ||||
|  | ||||
|         // Query registry for provider address. | ||||
|         address providerAddress = getLiquidityProviderFromRegistry( | ||||
|             registryAddress, | ||||
|             takerToken, | ||||
|             makerToken | ||||
|         ); | ||||
|         // If provider doesn't exist, return all zeros. | ||||
|         if (providerAddress == address(0)) { | ||||
|             return makerTokenAmounts; | ||||
|         } | ||||
|  | ||||
|         for (uint256 i = 0; i < numSamples; i++) { | ||||
|             (bool didSucceed, bytes memory resultData) = | ||||
|                 providerAddress.staticcall.gas(DEFAULT_CALL_GAS)( | ||||
|                     abi.encodeWithSelector( | ||||
|                         ILiquidityProvider(0).getSellQuote.selector, | ||||
|                         takerToken, | ||||
|                         makerToken, | ||||
|                         takerTokenAmounts[i] | ||||
|                     )); | ||||
|             uint256 buyAmount = 0; | ||||
|             if (didSucceed) { | ||||
|                 buyAmount = abi.decode(resultData, (uint256)); | ||||
|             } else { | ||||
|                 // Exit early if the amount is too high for the liquidity provider to serve | ||||
|                 break; | ||||
|             } | ||||
|             makerTokenAmounts[i] = buyAmount; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Sample buy quotes from an arbitrary on-chain liquidity provider. | ||||
|     /// @param registryAddress Address of the liquidity provider registry contract. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param makerTokenAmounts Maker token buy amount for each sample. | ||||
|     /// @return takerTokenAmounts Taker amounts sold at each maker token | ||||
|     ///         amount. | ||||
|     function sampleBuysFromLiquidityProviderRegistry( | ||||
|         address registryAddress, | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] memory makerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory takerTokenAmounts) | ||||
|     { | ||||
|         // Initialize array of taker token amounts. | ||||
|         uint256 numSamples = makerTokenAmounts.length; | ||||
|         takerTokenAmounts = new uint256[](numSamples); | ||||
|  | ||||
|         // Query registry for provider address. | ||||
|         address providerAddress = getLiquidityProviderFromRegistry( | ||||
|             registryAddress, | ||||
|             takerToken, | ||||
|             makerToken | ||||
|         ); | ||||
|         // If provider doesn't exist, return all zeros. | ||||
|         if (providerAddress == address(0)) { | ||||
|             return takerTokenAmounts; | ||||
|         } | ||||
|  | ||||
|         // Otherwise, query liquidity provider for quotes. | ||||
|         for (uint256 i = 0; i < numSamples; i++) { | ||||
|             (bool didSucceed, bytes memory resultData) = | ||||
|                 providerAddress.staticcall.gas(DEFAULT_CALL_GAS)( | ||||
|                     abi.encodeWithSelector( | ||||
|                         ILiquidityProvider(0).getBuyQuote.selector, | ||||
|                         takerToken, | ||||
|                         makerToken, | ||||
|                         makerTokenAmounts[i] | ||||
|                     )); | ||||
|             uint256 sellAmount = 0; | ||||
|             if (didSucceed) { | ||||
|                 sellAmount = abi.decode(resultData, (uint256)); | ||||
|             } else { | ||||
|                 // Exit early if the amount is too high for the liquidity provider to serve | ||||
|                 break; | ||||
|             } | ||||
|             takerTokenAmounts[i] = sellAmount; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Returns the address of a liquidity provider for the given market | ||||
|     ///      (takerToken, makerToken), from a registry of liquidity providers. | ||||
|     ///      Returns address(0) if no such provider exists in the registry. | ||||
|     /// @param takerToken Taker asset managed by liquidity provider. | ||||
|     /// @param makerToken Maker asset managed by liquidity provider. | ||||
|     /// @return providerAddress Address of the liquidity provider. | ||||
|     function getLiquidityProviderFromRegistry( | ||||
|         address registryAddress, | ||||
|         address takerToken, | ||||
|         address makerToken | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (address providerAddress) | ||||
|     { | ||||
|         bytes memory callData = abi.encodeWithSelector( | ||||
|             ILiquidityProviderRegistry(0).getLiquidityProviderForMarket.selector, | ||||
|             takerToken, | ||||
|             makerToken | ||||
|         ); | ||||
|         (bool didSucceed, bytes memory returnData) = registryAddress.staticcall(callData); | ||||
|         if (didSucceed && returnData.length == 32) { | ||||
|             return LibBytes.readAddress(returnData, 12); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Overridable way to get token decimals. | ||||
|     /// @param tokenAddress Address of the token. | ||||
|     /// @return decimals The decimal places for the token. | ||||
|     function _getTokenDecimals(address tokenAddress) | ||||
|         internal | ||||
|         view | ||||
|         returns (uint8 decimals) | ||||
|     { | ||||
|         return LibERC20Token.decimals(tokenAddress); | ||||
|     } | ||||
|  | ||||
|     /// @dev Gracefully calls a Uniswap pricing function. | ||||
|     /// @param uniswapExchangeAddress Address of an `IUniswapExchangeQuotes` exchange. | ||||
|     /// @param functionSelector Selector of the target function. | ||||
|     /// @param inputAmount Quantity parameter particular to the pricing function. | ||||
|     /// @return outputAmount The returned amount from the function call. Will be | ||||
|     ///         zero if the call fails or if `uniswapExchangeAddress` is zero. | ||||
|     function _callUniswapExchangePriceFunction( | ||||
|         address uniswapExchangeAddress, | ||||
|         bytes4 functionSelector, | ||||
|         uint256 inputAmount | ||||
|     ) | ||||
|         private | ||||
|         view | ||||
|         returns (uint256 outputAmount, bool didSucceed) | ||||
|     { | ||||
|         if (uniswapExchangeAddress == address(0)) { | ||||
|             return (outputAmount, didSucceed); | ||||
|         } | ||||
|         bytes memory resultData; | ||||
|         (didSucceed, resultData) = | ||||
|             uniswapExchangeAddress.staticcall.gas(UNISWAP_CALL_GAS)( | ||||
|                 abi.encodeWithSelector( | ||||
|                     functionSelector, | ||||
|                     inputAmount | ||||
|                 )); | ||||
|         if (didSucceed) { | ||||
|             outputAmount = abi.decode(resultData, (uint256)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Retrive an existing Uniswap exchange contract. | ||||
|     ///      Throws if the exchange does not exist. | ||||
|     /// @param tokenAddress Address of the token contract. | ||||
|     /// @return exchange `IUniswapExchangeQuotes` for the token. | ||||
|     function _getUniswapExchange(address tokenAddress) | ||||
|         private | ||||
|         view | ||||
|         returns (IUniswapExchangeQuotes exchange) | ||||
|     { | ||||
|         exchange = IUniswapExchangeQuotes( | ||||
|             address(IUniswapExchangeFactory(_getUniswapExchangeFactoryAddress()) | ||||
|             .getExchange(tokenAddress)) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Assert that the tokens in a trade pair are valid. | ||||
|     /// @param makerToken Address of the maker token. | ||||
|     /// @param takerToken Address of the taker token. | ||||
|     function _assertValidPair(address makerToken, address takerToken) | ||||
|         private | ||||
|         pure | ||||
|     { | ||||
|         require(makerToken != takerToken, "ERC20BridgeSampler/INVALID_TOKEN_PAIR"); | ||||
|     } | ||||
| } | ||||
| @@ -1,45 +0,0 @@ | ||||
| /* | ||||
|  | ||||
|   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.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol"; | ||||
|  | ||||
|  | ||||
| interface IDevUtils { | ||||
|  | ||||
|     /// @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 calldata order, bytes calldata signature) | ||||
|         external | ||||
|         view | ||||
|         returns ( | ||||
|             LibOrder.OrderInfo memory orderInfo, | ||||
|             uint256 fillableTakerAssetAmount, | ||||
|             bool isValidSignature | ||||
|         ); | ||||
| } | ||||
| @@ -1,201 +0,0 @@ | ||||
| /* | ||||
|  | ||||
|   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.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol"; | ||||
|  | ||||
|  | ||||
| interface IERC20BridgeSampler { | ||||
|  | ||||
|     /// @dev Call multiple public functions on this contract in a single transaction. | ||||
|     /// @param callDatas ABI-encoded call data for each function call. | ||||
|     /// @return callResults ABI-encoded results data for each call. | ||||
|     function batchCall(bytes[] calldata callDatas) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes[] memory callResults); | ||||
|  | ||||
|     /// @dev Queries the fillable taker asset amounts of native orders. | ||||
|     /// @param orders Native orders to query. | ||||
|     /// @param orderSignatures Signatures for each respective order in `orders`. | ||||
|     /// @return orderFillableTakerAssetAmounts How much taker asset can be filled | ||||
|     ///         by each order in `orders`. | ||||
|     function getOrderFillableTakerAssetAmounts( | ||||
|         LibOrder.Order[] calldata orders, | ||||
|         bytes[] calldata orderSignatures | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256[] memory orderFillableTakerAssetAmounts); | ||||
|  | ||||
|     /// @dev Queries the fillable maker asset amounts of native orders. | ||||
|     /// @param orders Native orders to query. | ||||
|     /// @param orderSignatures Signatures for each respective order in `orders`. | ||||
|     /// @return orderFillableMakerAssetAmounts How much maker asset can be filled | ||||
|     ///         by each order in `orders`. | ||||
|     function getOrderFillableMakerAssetAmounts( | ||||
|         LibOrder.Order[] calldata orders, | ||||
|         bytes[] calldata orderSignatures | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256[] memory orderFillableMakerAssetAmounts); | ||||
|  | ||||
|     /// @dev Sample sell quotes from Kyber. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromKyberNetwork( | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] calldata takerTokenAmounts | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts); | ||||
|  | ||||
|     /// @dev Sample sell quotes from Eth2Dai/Oasis. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromEth2Dai( | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] calldata takerTokenAmounts | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts); | ||||
|  | ||||
|     /// @dev Sample sell quotes from Uniswap. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromUniswap( | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] calldata takerTokenAmounts | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts); | ||||
|  | ||||
|     /// @dev Sample buy quotes from Uniswap. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param makerTokenAmounts Maker token sell amount for each sample. | ||||
|     /// @return takerTokenAmounts Taker amounts sold at each maker token | ||||
|     ///         amount. | ||||
|     function sampleBuysFromUniswap( | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] calldata makerTokenAmounts | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256[] memory takerTokenAmounts); | ||||
|  | ||||
|     /// @dev Sample buy quotes from Eth2Dai/Oasis. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Maker token sell amount for each sample. | ||||
|     /// @return takerTokenAmounts Taker amounts sold at each maker token | ||||
|     ///         amount. | ||||
|     function sampleBuysFromEth2Dai( | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] calldata makerTokenAmounts | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256[] memory takerTokenAmounts); | ||||
|  | ||||
|     /// @dev Sample sell quotes from Curve. | ||||
|     /// @param curveAddress Address of the Curve contract. | ||||
|     /// @param fromTokenIdx Index of the taker token (what to sell). | ||||
|     /// @param toTokenIdx Index of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromCurve( | ||||
|         address curveAddress, | ||||
|         int128 fromTokenIdx, | ||||
|         int128 toTokenIdx, | ||||
|         uint256[] calldata takerTokenAmounts | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts); | ||||
|  | ||||
|     /// @dev Sample sell quotes from an arbitrary on-chain liquidity provider. | ||||
|     /// @param registryAddress Address of the liquidity provider registry contract. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromLiquidityProviderRegistry( | ||||
|         address registryAddress, | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] calldata takerTokenAmounts | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts); | ||||
|  | ||||
|     /// @dev Sample buy quotes from an arbitrary on-chain liquidity provider. | ||||
|     /// @param registryAddress Address of the liquidity provider registry contract. | ||||
|     /// @param takerToken Address of the taker token (what to sell). | ||||
|     /// @param makerToken Address of the maker token (what to buy). | ||||
|     /// @param makerTokenAmounts Maker token buy amount for each sample. | ||||
|     /// @return takerTokenAmounts Taker amounts sold at each maker token | ||||
|     ///         amount. | ||||
|     function sampleBuysFromLiquidityProviderRegistry( | ||||
|         address registryAddress, | ||||
|         address takerToken, | ||||
|         address makerToken, | ||||
|         uint256[] calldata makerTokenAmounts | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256[] memory takerTokenAmounts); | ||||
|  | ||||
|     /// @dev Returns the address of a liquidity provider for the given market | ||||
|     ///      (takerToken, makerToken), from a registry of liquidity providers. | ||||
|     ///      Returns address(0) if no such provider exists in the registry. | ||||
|     /// @param takerToken Taker asset managed by liquidity provider. | ||||
|     /// @param makerToken Maker asset managed by liquidity provider. | ||||
|     /// @return providerAddress Address of the liquidity provider. | ||||
|     function getLiquidityProviderFromRegistry( | ||||
|         address registryAddress, | ||||
|         address takerToken, | ||||
|         address makerToken | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (address providerAddress); | ||||
| } | ||||
| @@ -1,92 +0,0 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc20-bridge-sampler", | ||||
|     "version": "1.5.1", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
|     "description": "Sampler contracts for the 0x asset-swapper", | ||||
|     "main": "lib/src/index.js", | ||||
|     "directories": { | ||||
|         "test": "test" | ||||
|     }, | ||||
|     "scripts": { | ||||
|         "build": "yarn pre_build && tsc -b", | ||||
|         "build:ci": "yarn build", | ||||
|         "pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy", | ||||
|         "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 test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers", | ||||
|         "generate_contract_wrappers": "abi-gen --debug --abis  ${npm_package_config_abis} --output test/generated-wrappers --backend ethers", | ||||
|         "lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", | ||||
|         "fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-wrappers/**/* --exclude ./test/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 generate", | ||||
|         "contracts:copy": "contracts-gen copy", | ||||
|         "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol", | ||||
|         "compile:truffle": "truffle compile" | ||||
|     }, | ||||
|     "config": { | ||||
|         "publicInterfaceContracts": "ERC20BridgeSampler,IERC20BridgeSampler,ILiquidityProvider,ILiquidityProviderRegistry", | ||||
|         "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", | ||||
|         "abis": "./test/generated-artifacts/@(ERC20BridgeSampler|ICurve|IDevUtils|IERC20BridgeSampler|IEth2Dai|IKyberNetwork|ILiquidityProvider|ILiquidityProviderRegistry|IUniswapExchangeQuotes|TestERC20BridgeSampler).json" | ||||
|     }, | ||||
|     "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/protocol/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.2.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.2.5", | ||||
|         "@0x/contracts-erc20": "^3.1.5", | ||||
|         "@0x/contracts-exchange": "^3.2.5", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.5", | ||||
|         "@0x/contracts-gen": "^2.0.8", | ||||
|         "@0x/contracts-test-utils": "^5.3.2", | ||||
|         "@0x/contracts-utils": "^4.4.3", | ||||
|         "@0x/dev-utils": "^3.2.1", | ||||
|         "@0x/sol-compiler": "^4.0.8", | ||||
|         "@0x/tslint-config": "^4.0.0", | ||||
|         "@0x/web3-wrapper": "^7.0.7", | ||||
|         "@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", | ||||
|         "truffle": "^5.0.32", | ||||
|         "tslint": "5.11.0", | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.1", | ||||
|         "@0x/types": "^3.1.2", | ||||
|         "@0x/typescript-typings": "^5.0.2", | ||||
|         "@0x/utils": "^5.4.1", | ||||
|         "ethereum-types": "^3.1.0", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|     } | ||||
| } | ||||
| @@ -1,17 +0,0 @@ | ||||
| /* | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
| import { ContractArtifact } from 'ethereum-types'; | ||||
|  | ||||
| import * as ERC20BridgeSampler from '../generated-artifacts/ERC20BridgeSampler.json'; | ||||
| import * as IERC20BridgeSampler from '../generated-artifacts/IERC20BridgeSampler.json'; | ||||
| import * as ILiquidityProvider from '../generated-artifacts/ILiquidityProvider.json'; | ||||
| import * as ILiquidityProviderRegistry from '../generated-artifacts/ILiquidityProviderRegistry.json'; | ||||
| export const artifacts = { | ||||
|     ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact, | ||||
|     IERC20BridgeSampler: IERC20BridgeSampler as ContractArtifact, | ||||
|     ILiquidityProvider: ILiquidityProvider as ContractArtifact, | ||||
|     ILiquidityProviderRegistry: ILiquidityProviderRegistry as ContractArtifact, | ||||
| }; | ||||
| @@ -1,2 +0,0 @@ | ||||
| export * from './wrappers'; | ||||
| export * from './artifacts'; | ||||
| @@ -1,29 +0,0 @@ | ||||
| /* | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
| import { ContractArtifact } from 'ethereum-types'; | ||||
|  | ||||
| import * as ERC20BridgeSampler from '../test/generated-artifacts/ERC20BridgeSampler.json'; | ||||
| import * as ICurve from '../test/generated-artifacts/ICurve.json'; | ||||
| import * as IDevUtils from '../test/generated-artifacts/IDevUtils.json'; | ||||
| import * as IERC20BridgeSampler from '../test/generated-artifacts/IERC20BridgeSampler.json'; | ||||
| import * as IEth2Dai from '../test/generated-artifacts/IEth2Dai.json'; | ||||
| import * as IKyberNetwork from '../test/generated-artifacts/IKyberNetwork.json'; | ||||
| import * as ILiquidityProvider from '../test/generated-artifacts/ILiquidityProvider.json'; | ||||
| import * as ILiquidityProviderRegistry from '../test/generated-artifacts/ILiquidityProviderRegistry.json'; | ||||
| import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExchangeQuotes.json'; | ||||
| import * as TestERC20BridgeSampler from '../test/generated-artifacts/TestERC20BridgeSampler.json'; | ||||
| export const artifacts = { | ||||
|     ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact, | ||||
|     ICurve: ICurve as ContractArtifact, | ||||
|     IDevUtils: IDevUtils as ContractArtifact, | ||||
|     IERC20BridgeSampler: IERC20BridgeSampler as ContractArtifact, | ||||
|     IEth2Dai: IEth2Dai as ContractArtifact, | ||||
|     IKyberNetwork: IKyberNetwork as ContractArtifact, | ||||
|     ILiquidityProvider: ILiquidityProvider as ContractArtifact, | ||||
|     ILiquidityProviderRegistry: ILiquidityProviderRegistry as ContractArtifact, | ||||
|     IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact, | ||||
|     TestERC20BridgeSampler: TestERC20BridgeSampler as ContractArtifact, | ||||
| }; | ||||
| @@ -1,15 +0,0 @@ | ||||
| /* | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
| export * from '../test/generated-wrappers/erc20_bridge_sampler'; | ||||
| export * from '../test/generated-wrappers/i_curve'; | ||||
| export * from '../test/generated-wrappers/i_dev_utils'; | ||||
| export * from '../test/generated-wrappers/i_erc20_bridge_sampler'; | ||||
| export * from '../test/generated-wrappers/i_eth2_dai'; | ||||
| export * from '../test/generated-wrappers/i_kyber_network'; | ||||
| export * from '../test/generated-wrappers/i_liquidity_provider'; | ||||
| export * from '../test/generated-wrappers/i_liquidity_provider_registry'; | ||||
| export * from '../test/generated-wrappers/i_uniswap_exchange_quotes'; | ||||
| export * from '../test/generated-wrappers/test_erc20_bridge_sampler'; | ||||
| @@ -1,22 +0,0 @@ | ||||
| { | ||||
|     "extends": "../../tsconfig", | ||||
|     "compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true }, | ||||
|     "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"], | ||||
|     "files": [ | ||||
|         "generated-artifacts/ERC20BridgeSampler.json", | ||||
|         "generated-artifacts/IERC20BridgeSampler.json", | ||||
|         "generated-artifacts/ILiquidityProvider.json", | ||||
|         "generated-artifacts/ILiquidityProviderRegistry.json", | ||||
|         "test/generated-artifacts/ERC20BridgeSampler.json", | ||||
|         "test/generated-artifacts/ICurve.json", | ||||
|         "test/generated-artifacts/IDevUtils.json", | ||||
|         "test/generated-artifacts/IERC20BridgeSampler.json", | ||||
|         "test/generated-artifacts/IEth2Dai.json", | ||||
|         "test/generated-artifacts/IKyberNetwork.json", | ||||
|         "test/generated-artifacts/ILiquidityProvider.json", | ||||
|         "test/generated-artifacts/ILiquidityProviderRegistry.json", | ||||
|         "test/generated-artifacts/IUniswapExchangeQuotes.json", | ||||
|         "test/generated-artifacts/TestERC20BridgeSampler.json" | ||||
|     ], | ||||
|     "exclude": ["./deploy/solc/solc_bin"] | ||||
| } | ||||
| @@ -1,4 +1,180 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1611648096, | ||||
|         "version": "3.3.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1610510890, | ||||
|         "version": "3.3.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.3.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add SPDX license identifiers to solidity files", | ||||
|                 "pr": 105 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Allow for excess return data in `LibERC20TokenV06` compat* functions", | ||||
|                 "pr": 97 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1609802516 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608692071, | ||||
|         "version": "3.2.14", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608245516, | ||||
|         "version": "3.2.13", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607485227, | ||||
|         "version": "3.2.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607381756, | ||||
|         "version": "3.2.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1606961263, | ||||
|         "version": "3.2.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605763885, | ||||
|         "version": "3.2.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605302002, | ||||
|         "version": "3.2.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604385937, | ||||
|         "version": "3.2.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604376968, | ||||
|         "version": "3.2.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604355662, | ||||
|         "version": "3.2.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603851023, | ||||
|         "version": "3.2.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603833198, | ||||
|         "version": "3.2.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603265572, | ||||
|         "version": "3.2.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1594788383, | ||||
|         "version": "3.2.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "3.2.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add `LibERC20Token.approveIfBelow()`", | ||||
|                 "pr": 2512 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add solidity 0.6 contracts", | ||||
|                 "pr": 2545 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Update `LibERC20TokenV06` comments.", | ||||
|                 "pr": 2597 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1592969527 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1583220306, | ||||
|         "version": "3.1.5", | ||||
|   | ||||
| @@ -5,6 +5,81 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.3.2 - _January 26, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.3.1 - _January 13, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.3.0 - _January 4, 2021_ | ||||
|  | ||||
|     * Add SPDX license identifiers to solidity files (#105) | ||||
|     * Allow for excess return data in `LibERC20TokenV06` compat* functions (#97) | ||||
|  | ||||
| ## v3.2.14 - _December 23, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.13 - _December 17, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.12 - _December 9, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.11 - _December 7, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.10 - _December 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.9 - _November 19, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.8 - _November 13, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.7 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.6 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.5 - _November 2, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.4 - _October 28, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.3 - _October 27, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.2 - _October 21, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.1 - _July 15, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.0 - _June 24, 2020_ | ||||
|  | ||||
|     * Add `LibERC20Token.approveIfBelow()` (#2512) | ||||
|     * Add solidity 0.6 contracts (#2545) | ||||
|     * Update `LibERC20TokenV06` comments. (#2597) | ||||
|  | ||||
| ## v3.1.5 - _March 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -47,6 +47,25 @@ library LibERC20Token { | ||||
|         _callWithOptionalBooleanResult(token, callData); | ||||
|     } | ||||
|  | ||||
|     /// @dev Calls `IERC20Token(token).approve()` and sets the allowance to the | ||||
|     ///      maximum if the current approval is not already >= an amount. | ||||
|     ///      Reverts if `false` is returned or if the return | ||||
|     ///      data length is nonzero and not 32 bytes. | ||||
|     /// @param token The address of the token contract. | ||||
|     /// @param spender The address that receives an allowance. | ||||
|     /// @param amount The minimum allowance needed. | ||||
|     function approveIfBelow( | ||||
|         address token, | ||||
|         address spender, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         internal | ||||
|     { | ||||
|         if (IERC20Token(token).allowance(address(this), spender) < amount) { | ||||
|             approve(token, spender, uint256(-1)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Calls `IERC20Token(token).transfer()`. | ||||
|     ///      Reverts if `false` is returned or if the return | ||||
|     ///      data length is nonzero and not 32 bytes. | ||||
|   | ||||
							
								
								
									
										96
									
								
								contracts/erc20/contracts/src/v06/IERC20TokenV06.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								contracts/erc20/contracts/src/v06/IERC20TokenV06.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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.6.5; | ||||
|  | ||||
|  | ||||
| interface IERC20TokenV06 { | ||||
|  | ||||
|     // solhint-disable no-simple-event-func-name | ||||
|     event Transfer( | ||||
|         address indexed from, | ||||
|         address indexed to, | ||||
|         uint256 value | ||||
|     ); | ||||
|  | ||||
|     event Approval( | ||||
|         address indexed owner, | ||||
|         address indexed spender, | ||||
|         uint256 value | ||||
|     ); | ||||
|  | ||||
|     /// @dev send `value` token to `to` from `msg.sender` | ||||
|     /// @param to The address of the recipient | ||||
|     /// @param value The amount of token to be transferred | ||||
|     /// @return True if transfer was successful | ||||
|     function transfer(address to, uint256 value) | ||||
|         external | ||||
|         returns (bool); | ||||
|  | ||||
|     /// @dev send `value` token to `to` from `from` on the condition it is approved by `from` | ||||
|     /// @param from The address of the sender | ||||
|     /// @param to The address of the recipient | ||||
|     /// @param value The amount of token to be transferred | ||||
|     /// @return True if transfer was successful | ||||
|     function transferFrom( | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 value | ||||
|     ) | ||||
|         external | ||||
|         returns (bool); | ||||
|  | ||||
|     /// @dev `msg.sender` approves `spender` to spend `value` tokens | ||||
|     /// @param spender The address of the account able to transfer the tokens | ||||
|     /// @param value The amount of wei to be approved for transfer | ||||
|     /// @return Always true if the call has enough gas to complete execution | ||||
|     function approve(address spender, uint256 value) | ||||
|         external | ||||
|         returns (bool); | ||||
|  | ||||
|     /// @dev Query total supply of token | ||||
|     /// @return Total supply of token | ||||
|     function totalSupply() | ||||
|         external | ||||
|         view | ||||
|         returns (uint256); | ||||
|  | ||||
|     /// @dev Get the balance of `owner`. | ||||
|     /// @param owner The address from which the balance will be retrieved | ||||
|     /// @return Balance of owner | ||||
|     function balanceOf(address owner) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256); | ||||
|  | ||||
|     /// @dev Get the allowance for `spender` to spend from `owner`. | ||||
|     /// @param owner The address of the account owning tokens | ||||
|     /// @param spender The address of the account able to transfer the tokens | ||||
|     /// @return Amount of remaining tokens allowed to spent | ||||
|     function allowance(address owner, address spender) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256); | ||||
|  | ||||
|     /// @dev Get the number of decimals this token has. | ||||
|     function decimals() | ||||
|         external | ||||
|         view | ||||
|         returns (uint8); | ||||
| } | ||||
							
								
								
									
										33
									
								
								contracts/erc20/contracts/src/v06/IEtherTokenV06.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								contracts/erc20/contracts/src/v06/IEtherTokenV06.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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.6.5; | ||||
|  | ||||
| import "./IERC20TokenV06.sol"; | ||||
|  | ||||
|  | ||||
| interface IEtherTokenV06 is | ||||
|     IERC20TokenV06 | ||||
| { | ||||
|     /// @dev Wrap ether. | ||||
|     function deposit() external payable; | ||||
|  | ||||
|     /// @dev Unwrap ether. | ||||
|     function withdraw(uint256 amount) external; | ||||
| } | ||||
							
								
								
									
										209
									
								
								contracts/erc20/contracts/src/v06/LibERC20TokenV06.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								contracts/erc20/contracts/src/v06/LibERC20TokenV06.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,209 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 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.6.5; | ||||
|  | ||||
| import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol"; | ||||
| import "./IERC20TokenV06.sol"; | ||||
|  | ||||
|  | ||||
| library LibERC20TokenV06 { | ||||
|     bytes constant private DECIMALS_CALL_DATA = hex"313ce567"; | ||||
|  | ||||
|     /// @dev Calls `IERC20TokenV06(token).approve()`. | ||||
|     ///      Reverts if the result fails `isSuccessfulResult()` or the call reverts. | ||||
|     /// @param token The address of the token contract. | ||||
|     /// @param spender The address that receives an allowance. | ||||
|     /// @param allowance The allowance to set. | ||||
|     function compatApprove( | ||||
|         IERC20TokenV06 token, | ||||
|         address spender, | ||||
|         uint256 allowance | ||||
|     ) | ||||
|         internal | ||||
|     { | ||||
|         bytes memory callData = abi.encodeWithSelector( | ||||
|             token.approve.selector, | ||||
|             spender, | ||||
|             allowance | ||||
|         ); | ||||
|         _callWithOptionalBooleanResult(address(token), callData); | ||||
|     } | ||||
|  | ||||
|     /// @dev Calls `IERC20TokenV06(token).approve()` and sets the allowance to the | ||||
|     ///      maximum if the current approval is not already >= an amount. | ||||
|     ///      Reverts if the result fails `isSuccessfulResult()` or the call reverts. | ||||
|     /// @param token The address of the token contract. | ||||
|     /// @param spender The address that receives an allowance. | ||||
|     /// @param amount The minimum allowance needed. | ||||
|     function approveIfBelow( | ||||
|         IERC20TokenV06 token, | ||||
|         address spender, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         internal | ||||
|     { | ||||
|         if (token.allowance(address(this), spender) < amount) { | ||||
|             compatApprove(token, spender, uint256(-1)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Calls `IERC20TokenV06(token).transfer()`. | ||||
|     ///      Reverts if the result fails `isSuccessfulResult()` or the call reverts. | ||||
|     /// @param token The address of the token contract. | ||||
|     /// @param to The address that receives the tokens | ||||
|     /// @param amount Number of tokens to transfer. | ||||
|     function compatTransfer( | ||||
|         IERC20TokenV06 token, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         internal | ||||
|     { | ||||
|         bytes memory callData = abi.encodeWithSelector( | ||||
|             token.transfer.selector, | ||||
|             to, | ||||
|             amount | ||||
|         ); | ||||
|         _callWithOptionalBooleanResult(address(token), callData); | ||||
|     } | ||||
|  | ||||
|     /// @dev Calls `IERC20TokenV06(token).transferFrom()`. | ||||
|     ///      Reverts if the result fails `isSuccessfulResult()` or the call reverts. | ||||
|     /// @param token The address of the token contract. | ||||
|     /// @param from The owner of the tokens. | ||||
|     /// @param to The address that receives the tokens | ||||
|     /// @param amount Number of tokens to transfer. | ||||
|     function compatTransferFrom( | ||||
|         IERC20TokenV06 token, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         internal | ||||
|     { | ||||
|         bytes memory callData = abi.encodeWithSelector( | ||||
|             token.transferFrom.selector, | ||||
|             from, | ||||
|             to, | ||||
|             amount | ||||
|         ); | ||||
|         _callWithOptionalBooleanResult(address(token), callData); | ||||
|     } | ||||
|  | ||||
|     /// @dev Retrieves the number of decimals for a token. | ||||
|     ///      Returns `18` if the call reverts. | ||||
|     /// @param token The address of the token contract. | ||||
|     /// @return tokenDecimals The number of decimals places for the token. | ||||
|     function compatDecimals(IERC20TokenV06 token) | ||||
|         internal | ||||
|         view | ||||
|         returns (uint8 tokenDecimals) | ||||
|     { | ||||
|         tokenDecimals = 18; | ||||
|         (bool didSucceed, bytes memory resultData) = address(token).staticcall(DECIMALS_CALL_DATA); | ||||
|         if (didSucceed && resultData.length >= 32) { | ||||
|             tokenDecimals = uint8(LibBytesV06.readUint256(resultData, 0)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Retrieves the allowance for a token, owner, and spender. | ||||
|     ///      Returns `0` if the call reverts. | ||||
|     /// @param token The address of the token contract. | ||||
|     /// @param owner The owner of the tokens. | ||||
|     /// @param spender The address the spender. | ||||
|     /// @return allowance_ The allowance for a token, owner, and spender. | ||||
|     function compatAllowance(IERC20TokenV06 token, address owner, address spender) | ||||
|         internal | ||||
|         view | ||||
|         returns (uint256 allowance_) | ||||
|     { | ||||
|         (bool didSucceed, bytes memory resultData) = address(token).staticcall( | ||||
|             abi.encodeWithSelector( | ||||
|                 token.allowance.selector, | ||||
|                 owner, | ||||
|                 spender | ||||
|             ) | ||||
|         ); | ||||
|         if (didSucceed && resultData.length >= 32) { | ||||
|             allowance_ = LibBytesV06.readUint256(resultData, 0); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Retrieves the balance for a token owner. | ||||
|     ///      Returns `0` if the call reverts. | ||||
|     /// @param token The address of the token contract. | ||||
|     /// @param owner The owner of the tokens. | ||||
|     /// @return balance The token balance of an owner. | ||||
|     function compatBalanceOf(IERC20TokenV06 token, address owner) | ||||
|         internal | ||||
|         view | ||||
|         returns (uint256 balance) | ||||
|     { | ||||
|         (bool didSucceed, bytes memory resultData) = address(token).staticcall( | ||||
|             abi.encodeWithSelector( | ||||
|                 token.balanceOf.selector, | ||||
|                 owner | ||||
|             ) | ||||
|         ); | ||||
|         if (didSucceed && resultData.length >= 32) { | ||||
|             balance = LibBytesV06.readUint256(resultData, 0); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Check if the data returned by a non-static call to an ERC20 token | ||||
|     ///      is a successful result. Supported functions are `transfer()`, | ||||
|     ///      `transferFrom()`, and `approve()`. | ||||
|     /// @param resultData The raw data returned by a non-static call to the ERC20 token. | ||||
|     /// @return isSuccessful Whether the result data indicates success. | ||||
|     function isSuccessfulResult(bytes memory resultData) | ||||
|         internal | ||||
|         pure | ||||
|         returns (bool isSuccessful) | ||||
|     { | ||||
|         if (resultData.length == 0) { | ||||
|             return true; | ||||
|         } | ||||
|         if (resultData.length >= 32) { | ||||
|             uint256 result = LibBytesV06.readUint256(resultData, 0); | ||||
|             if (result == 1) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Executes a call on address `target` with calldata `callData` | ||||
|     ///      and asserts that either nothing was returned or a single boolean | ||||
|     ///      was returned equal to `true`. | ||||
|     /// @param target The call target. | ||||
|     /// @param callData The abi-encoded call data. | ||||
|     function _callWithOptionalBooleanResult( | ||||
|         address target, | ||||
|         bytes memory callData | ||||
|     ) | ||||
|         private | ||||
|     { | ||||
|         (bool didSucceed, bytes memory resultData) = target.call(callData); | ||||
|         if (didSucceed && isSuccessfulResult(resultData)) { | ||||
|             return; | ||||
|         } | ||||
|         LibRichErrorsV06.rrevert(resultData); | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc20", | ||||
|     "version": "3.1.5", | ||||
|     "version": "3.3.2", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -38,39 +38,39 @@ | ||||
|     }, | ||||
|     "config": { | ||||
|         "publicInterfaceContracts": "DummyERC20Token,ERC20Token,WETH9,ZRXToken,DummyNoReturnERC20Token,DummyMultipleReturnERC20Token", | ||||
|         "abis": "./test/generated-artifacts/@(DummyERC20Token|DummyMultipleReturnERC20Token|DummyNoReturnERC20Token|ERC20Token|IERC20Token|IEtherToken|LibERC20Token|MintableERC20Token|TestLibERC20Token|TestLibERC20TokenTarget|UnlimitedAllowanceERC20Token|UntransferrableDummyERC20Token|WETH9|ZRXToken).json", | ||||
|         "abis": "./test/generated-artifacts/@(DummyERC20Token|DummyMultipleReturnERC20Token|DummyNoReturnERC20Token|ERC20Token|IERC20Token|IERC20TokenV06|IEtherToken|IEtherTokenV06|LibERC20Token|LibERC20TokenV06|MintableERC20Token|TestLibERC20Token|TestLibERC20TokenTarget|UnlimitedAllowanceERC20Token|UntransferrableDummyERC20Token|WETH9|ZRXToken).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" | ||||
|         "url": "https://github.com/0xProject/protocol.git" | ||||
|     }, | ||||
|     "license": "Apache-2.0", | ||||
|     "bugs": { | ||||
|         "url": "https://github.com/0xProject/0x-monorepo/issues" | ||||
|         "url": "https://github.com/0xProject/protocol/issues" | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md", | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.2.2", | ||||
|         "@0x/contracts-gen": "^2.0.8", | ||||
|         "@0x/contracts-test-utils": "^5.3.2", | ||||
|         "@0x/contracts-utils": "^4.4.3", | ||||
|         "@0x/dev-utils": "^3.2.1", | ||||
|         "@0x/sol-compiler": "^4.0.8", | ||||
|         "@0x/ts-doc-gen": "^0.0.22", | ||||
|         "@0x/tslint-config": "^4.0.0", | ||||
|         "@0x/types": "^3.1.2", | ||||
|         "@0x/typescript-typings": "^5.0.2", | ||||
|         "@0x/utils": "^5.4.1", | ||||
|         "@0x/web3-wrapper": "^7.0.7", | ||||
|         "@0x/abi-gen": "^5.4.19", | ||||
|         "@0x/contracts-gen": "^2.0.30", | ||||
|         "@0x/contracts-test-utils": "^5.3.20", | ||||
|         "@0x/contracts-utils": "^4.7.2", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.5.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "@types/node": "12.12.54", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereum-types": "^3.1.0", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "lodash": "^4.17.11", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
| @@ -78,13 +78,14 @@ | ||||
|         "shx": "^0.2.2", | ||||
|         "solhint": "^1.4.1", | ||||
|         "tslint": "5.11.0", | ||||
|         "typedoc": "^0.15.0", | ||||
|         "typedoc": "~0.16.11", | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.1" | ||||
|         "@0x/base-contract": "^6.2.18" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|     } | ||||
|     }, | ||||
|     "gitHead": "4f91bfd907996b2f4dd383778b50c479c2602b56" | ||||
| } | ||||
|   | ||||
| @@ -10,8 +10,11 @@ import * as DummyMultipleReturnERC20Token from '../test/generated-artifacts/Dumm | ||||
| import * as DummyNoReturnERC20Token from '../test/generated-artifacts/DummyNoReturnERC20Token.json'; | ||||
| import * as ERC20Token from '../test/generated-artifacts/ERC20Token.json'; | ||||
| import * as IERC20Token from '../test/generated-artifacts/IERC20Token.json'; | ||||
| import * as IERC20TokenV06 from '../test/generated-artifacts/IERC20TokenV06.json'; | ||||
| import * as IEtherToken from '../test/generated-artifacts/IEtherToken.json'; | ||||
| import * as IEtherTokenV06 from '../test/generated-artifacts/IEtherTokenV06.json'; | ||||
| import * as LibERC20Token from '../test/generated-artifacts/LibERC20Token.json'; | ||||
| import * as LibERC20TokenV06 from '../test/generated-artifacts/LibERC20TokenV06.json'; | ||||
| import * as MintableERC20Token from '../test/generated-artifacts/MintableERC20Token.json'; | ||||
| import * as TestLibERC20Token from '../test/generated-artifacts/TestLibERC20Token.json'; | ||||
| import * as TestLibERC20TokenTarget from '../test/generated-artifacts/TestLibERC20TokenTarget.json'; | ||||
| @@ -28,6 +31,9 @@ export const artifacts = { | ||||
|     ZRXToken: (ZRXToken as any) as ContractArtifact, | ||||
|     IERC20Token: IERC20Token as ContractArtifact, | ||||
|     IEtherToken: IEtherToken as ContractArtifact, | ||||
|     IERC20TokenV06: IERC20TokenV06 as ContractArtifact, | ||||
|     IEtherTokenV06: IEtherTokenV06 as ContractArtifact, | ||||
|     LibERC20TokenV06: LibERC20TokenV06 as ContractArtifact, | ||||
|     DummyERC20Token: DummyERC20Token as ContractArtifact, | ||||
|     DummyMultipleReturnERC20Token: DummyMultipleReturnERC20Token as ContractArtifact, | ||||
|     DummyNoReturnERC20Token: DummyNoReturnERC20Token as ContractArtifact, | ||||
|   | ||||
| @@ -8,8 +8,11 @@ export * from '../test/generated-wrappers/dummy_multiple_return_erc20_token'; | ||||
| export * from '../test/generated-wrappers/dummy_no_return_erc20_token'; | ||||
| export * from '../test/generated-wrappers/erc20_token'; | ||||
| export * from '../test/generated-wrappers/i_erc20_token'; | ||||
| export * from '../test/generated-wrappers/i_erc20_token_v06'; | ||||
| export * from '../test/generated-wrappers/i_ether_token'; | ||||
| export * from '../test/generated-wrappers/i_ether_token_v06'; | ||||
| export * from '../test/generated-wrappers/lib_erc20_token'; | ||||
| export * from '../test/generated-wrappers/lib_erc20_token_v06'; | ||||
| export * from '../test/generated-wrappers/mintable_erc20_token'; | ||||
| export * from '../test/generated-wrappers/test_lib_erc20_token'; | ||||
| export * from '../test/generated-wrappers/test_lib_erc20_token_target'; | ||||
|   | ||||
| @@ -14,8 +14,11 @@ | ||||
|         "test/generated-artifacts/DummyNoReturnERC20Token.json", | ||||
|         "test/generated-artifacts/ERC20Token.json", | ||||
|         "test/generated-artifacts/IERC20Token.json", | ||||
|         "test/generated-artifacts/IERC20TokenV06.json", | ||||
|         "test/generated-artifacts/IEtherToken.json", | ||||
|         "test/generated-artifacts/IEtherTokenV06.json", | ||||
|         "test/generated-artifacts/LibERC20Token.json", | ||||
|         "test/generated-artifacts/LibERC20TokenV06.json", | ||||
|         "test/generated-artifacts/MintableERC20Token.json", | ||||
|         "test/generated-artifacts/TestLibERC20Token.json", | ||||
|         "test/generated-artifacts/TestLibERC20TokenTarget.json", | ||||
|   | ||||
| @@ -1,4 +1,166 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1611648096, | ||||
|         "version": "3.1.23", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1610510890, | ||||
|         "version": "3.1.22", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1609802516, | ||||
|         "version": "3.1.21", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608692071, | ||||
|         "version": "3.1.20", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608245516, | ||||
|         "version": "3.1.19", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607485227, | ||||
|         "version": "3.1.18", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607381756, | ||||
|         "version": "3.1.17", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1606961263, | ||||
|         "version": "3.1.16", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605763885, | ||||
|         "version": "3.1.15", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605302002, | ||||
|         "version": "3.1.14", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604385937, | ||||
|         "version": "3.1.13", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604376968, | ||||
|         "version": "3.1.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604355662, | ||||
|         "version": "3.1.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603851023, | ||||
|         "version": "3.1.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603833198, | ||||
|         "version": "3.1.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603265572, | ||||
|         "version": "3.1.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1594788383, | ||||
|         "version": "3.1.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1592969527, | ||||
|         "version": "3.1.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1583220306, | ||||
|         "version": "3.1.5", | ||||
|   | ||||
| @@ -5,6 +5,78 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.1.23 - _January 26, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.22 - _January 13, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.21 - _January 4, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.20 - _December 23, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.19 - _December 17, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.18 - _December 9, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.17 - _December 7, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.16 - _December 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.15 - _November 19, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.14 - _November 13, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.13 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.12 - _November 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.11 - _November 2, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.10 - _October 28, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.9 - _October 27, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.8 - _October 21, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.7 - _July 15, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.6 - _June 24, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.5 - _March 3, 2020_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc721", | ||||
|     "version": "3.1.5", | ||||
|     "version": "3.1.23", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -44,34 +44,34 @@ | ||||
|     }, | ||||
|     "repository": { | ||||
|         "type": "git", | ||||
|         "url": "https://github.com/0xProject/0x-monorepo.git" | ||||
|         "url": "https://github.com/0xProject/protocol.git" | ||||
|     }, | ||||
|     "license": "Apache-2.0", | ||||
|     "bugs": { | ||||
|         "url": "https://github.com/0xProject/0x-monorepo/issues" | ||||
|         "url": "https://github.com/0xProject/protocol/issues" | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md", | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.2.2", | ||||
|         "@0x/contracts-gen": "^2.0.8", | ||||
|         "@0x/contracts-test-utils": "^5.3.2", | ||||
|         "@0x/contracts-utils": "^4.4.3", | ||||
|         "@0x/dev-utils": "^3.2.1", | ||||
|         "@0x/sol-compiler": "^4.0.8", | ||||
|         "@0x/ts-doc-gen": "^0.0.22", | ||||
|         "@0x/tslint-config": "^4.0.0", | ||||
|         "@0x/types": "^3.1.2", | ||||
|         "@0x/typescript-typings": "^5.0.2", | ||||
|         "@0x/utils": "^5.4.1", | ||||
|         "@0x/web3-wrapper": "^7.0.7", | ||||
|         "@0x/abi-gen": "^5.4.19", | ||||
|         "@0x/contracts-gen": "^2.0.30", | ||||
|         "@0x/contracts-test-utils": "^5.3.20", | ||||
|         "@0x/contracts-utils": "^4.7.2", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.5.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "*", | ||||
|         "@types/node": "12.12.54", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereum-types": "^3.1.0", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "lodash": "^4.17.11", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
| @@ -80,13 +80,14 @@ | ||||
|         "solhint": "^1.4.1", | ||||
|         "truffle": "^5.0.32", | ||||
|         "tslint": "5.11.0", | ||||
|         "typedoc": "^0.15.0", | ||||
|         "typedoc": "~0.16.11", | ||||
|         "typescript": "3.0.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.1" | ||||
|         "@0x/base-contract": "^6.2.18" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|     } | ||||
|     }, | ||||
|     "gitHead": "4f91bfd907996b2f4dd383778b50c479c2602b56" | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,175 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1611648096, | ||||
|         "version": "4.2.24", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1610510890, | ||||
|         "version": "4.2.23", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1609802516, | ||||
|         "version": "4.2.22", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608692071, | ||||
|         "version": "4.2.21", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608245516, | ||||
|         "version": "4.2.20", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1608105788, | ||||
|         "version": "4.2.19", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607485227, | ||||
|         "version": "4.2.18", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1607381756, | ||||
|         "version": "4.2.17", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1606961263, | ||||
|         "version": "4.2.16", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605763885, | ||||
|         "version": "4.2.15", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1605302002, | ||||
|         "version": "4.2.14", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604385937, | ||||
|         "version": "4.2.13", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604376968, | ||||
|         "version": "4.2.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1604355662, | ||||
|         "version": "4.2.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603851023, | ||||
|         "version": "4.2.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603833198, | ||||
|         "version": "4.2.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1603265572, | ||||
|         "version": "4.2.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1594788383, | ||||
|         "version": "4.2.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1592969527, | ||||
|         "version": "4.2.6", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1583220306, | ||||
|         "version": "4.2.5", | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user