Compare commits

...

121 Commits

Author SHA1 Message Date
Github Actions
aae46bef84 Publish
- @0x/contracts-asset-proxy@3.7.19
 - @0x/contracts-broker@1.1.37
 - @0x/contracts-coordinator@3.1.38
 - @0x/contracts-dev-utils@1.3.36
 - @0x/contracts-erc1155@2.1.37
 - @0x/contracts-erc20@3.3.16
 - @0x/contracts-erc721@3.1.37
 - @0x/contracts-exchange-forwarder@4.2.38
 - @0x/contracts-exchange-libs@4.3.37
 - @0x/contracts-exchange@3.2.38
 - @0x/contracts-extensions@6.2.32
 - @0x/contracts-integrations@2.7.64
 - @0x/contracts-multisig@4.1.38
 - @0x/contracts-staking@2.0.45
 - @0x/contracts-test-utils@5.4.8
 - @0x/contracts-treasury@1.3.2
 - @0x/contracts-utils@4.7.16
 - @0x/contracts-zero-ex@0.28.0
 - @0x/asset-swapper@16.25.0
 - @0x/contract-wrappers-test@12.2.53
 - @0x/migrations@8.1.1
 - @0x/protocol-utils@1.8.2
2021-08-16 02:03:23 +00:00
Github Actions
a0bb36954e Updated CHANGELOGS & MD docs 2021-08-16 02:03:19 +00:00
Jacob Evans
4f32f3174f fix: fallbacks duplicate check on source-index (#307) 2021-08-16 11:25:22 +10:00
Daniel Pyrathon
b84107d142 fix: Adds "MetricsProxy" that allows us to proxy Prometheus metrics across… (#300)
* Adds "MetricsProxy" that allows us to proxy Prometheus metrics across to the API

* added more metric

* update linting
2021-08-12 18:11:51 -07:00
mzhu25
b46eeadc64 Feat/multiplex/v2 (#263)
* Refactor Multiplex into multiple files

* Pull UniswapV3 into separate file

* Add support for multihop nested within batch sell

* Add useSelfBalance and recipient to _fillRfqOrder

* Expose onlySelf variant in UniswapV3Feature for Multiplex

* Add useSelfBalance and recipient to _transformERC20

* Add support for proportional fill amounts in batchSell

* Comments and renaming

* Unit tests

* Use caps for immutables

* Rename taker -> recipient in TransformContext and SettleOrderInfo

* lint

* Address nits

* Swallow reverts for LiquidityProvider and UniswapV2 batch sells

* Address spot-check findings (#279)

* Check didSucceed in _callWithOptionalBooleanResult

* Add takerToken=ETH support to OtcOrdersFeature (#287)

* Add takerToken=ETH support to OtcOrdersFeature

* Add batchFillTakerSignedOtcOrders

* Add support for OTC to Multiplex

* Address PR feedback

* Update TransformERC20Feature (#303)

* remove multiplex_utils

* Update changelog

* unbreak tests
2021-08-12 17:09:46 -07:00
Github Actions
692231c2ea Publish
- @0x/contracts-asset-proxy@3.7.18
 - @0x/contracts-broker@1.1.36
 - @0x/contracts-coordinator@3.1.37
 - @0x/contracts-dev-utils@1.3.35
 - @0x/contracts-erc1155@2.1.36
 - @0x/contracts-erc20@3.3.15
 - @0x/contracts-erc721@3.1.36
 - @0x/contracts-exchange-forwarder@4.2.37
 - @0x/contracts-exchange-libs@4.3.36
 - @0x/contracts-exchange@3.2.37
 - @0x/contracts-extensions@6.2.31
 - @0x/contracts-integrations@2.7.63
 - @0x/contracts-multisig@4.1.37
 - @0x/contracts-staking@2.0.44
 - @0x/contracts-test-utils@5.4.7
 - @0x/contracts-treasury@1.3.1
 - @0x/contracts-utils@4.7.15
 - @0x/contracts-zero-ex@0.27.1
 - @0x/asset-swapper@16.24.1
 - @0x/contract-addresses@6.6.0
 - @0x/contract-wrappers-test@12.2.52
 - @0x/contract-wrappers@13.17.4
 - @0x/migrations@8.1.0
 - @0x/order-utils@10.4.28
 - @0x/protocol-utils@1.8.1
2021-08-11 07:09:54 +00:00
Github Actions
3a1becc3e4 Updated CHANGELOGS & MD docs 2021-08-11 07:09:50 +00:00
David Walsh
3653e2d7f9 fix: Add ethers dependency to 0x/contracts-erc20 (#305) 2021-08-10 22:50:35 -06:00
mzhu25
65def38d98 Add treasury address to contract-addresses (#301)
* Add treasury address to contract-addresses

* Update changelogs
2021-08-06 00:28:47 -07:00
Github Actions
859c36cb10 Publish
- @0x/contracts-asset-proxy@3.7.17
 - @0x/contracts-broker@1.1.35
 - @0x/contracts-coordinator@3.1.36
 - @0x/contracts-dev-utils@1.3.34
 - @0x/contracts-erc1155@2.1.35
 - @0x/contracts-erc20@3.3.14
 - @0x/contracts-erc721@3.1.35
 - @0x/contracts-exchange-forwarder@4.2.36
 - @0x/contracts-exchange-libs@4.3.35
 - @0x/contracts-exchange@3.2.36
 - @0x/contracts-extensions@6.2.30
 - @0x/contracts-integrations@2.7.62
 - @0x/contracts-multisig@4.1.36
 - @0x/contracts-staking@2.0.43
 - @0x/contracts-test-utils@5.4.6
 - @0x/contracts-treasury@1.3.0
 - @0x/contracts-utils@4.7.14
 - @0x/contracts-zero-ex@0.27.0
 - @0x/asset-swapper@16.24.0
 - @0x/contract-addresses@6.5.0
 - @0x/contract-wrappers-test@12.2.51
 - @0x/contract-wrappers@13.17.3
 - @0x/migrations@8.0.12
 - @0x/order-utils@10.4.27
 - @0x/protocol-utils@1.8.0
2021-08-06 04:54:38 +00:00
Github Actions
3e34386812 Updated CHANGELOGS & MD docs 2021-08-06 04:54:34 +00:00
Jacob Evans
a35af11981 feat: Clipper (#299)
* feat: Clipper

* feat: Curve tricrypto2 (#302)

* Scope down the token list search space for Clipper

* update deployed addresses
2021-08-06 14:12:43 +10:00
mzhu25
59eabec71e Add proposal 1 and test (#298)
* Add proposal 1 and test

* update changelog
2021-08-05 13:10:36 -07:00
Github Actions
bf4c7e7d50 Publish
- @0x/contracts-integrations@2.7.61
 - @0x/asset-swapper@16.23.1
2021-07-29 15:23:54 +00:00
Github Actions
fd098ca4df Updated CHANGELOGS & MD docs 2021-07-29 15:23:49 +00:00
Lawrence Forman
c360f8d8fd Publish (#296)
- @0x/contracts-integrations@2.7.60
 - @0x/asset-swapper@16.23.0

Co-authored-by: Github Actions <github-actions@github.com>
2021-07-29 10:54:37 -04:00
Github Actions
b358559421 Publish
- @0x/contracts-integrations@2.7.60
 - @0x/asset-swapper@16.23.0
2021-07-16 22:11:44 +00:00
Github Actions
df5aad8e8e Updated CHANGELOGS & MD docs 2021-07-16 22:11:39 +00:00
Andreas Andreakis
8dbf79db59 fix: lint (#289) 2021-07-16 12:24:56 -07:00
Andreas Andreakis
1839608e84 feat: ACryptoS StableSwap (#284) 2021-07-15 15:19:40 -07:00
Github Actions
6e3e795b8b Publish
- @0x/contracts-integrations@2.7.59
 - @0x/asset-swapper@16.22.0
2021-07-13 22:19:54 +00:00
Github Actions
d9c410a7e3 Updated CHANGELOGS & MD docs 2021-07-13 22:19:49 +00:00
Romain Butteaud
609727afe8 feat: Saddle alETH, D4 pools (#283) 2021-07-13 14:22:16 -07:00
Romain Butteaud
8a5c74c0b4 feat: IronSwap (#281)
* feat: IronSwap

* feat: IronSwap, changelog

* feat: IronSwap, prettier
2021-07-13 14:07:45 -07:00
Github Actions
cd93f3b07e Publish
- @0x/contracts-integrations@2.7.58
 - @0x/asset-swapper@16.21.0
2021-07-10 08:00:34 +00:00
Github Actions
8397b12de6 Updated CHANGELOGS & MD docs 2021-07-10 08:00:29 +00:00
Romain Butteaud
3f85acec3a feat: JetSwap (#280)
* feat: JetSwap

* feat: JetSwap, changelog
2021-07-10 00:18:29 -07:00
phil-ociraptor
d6a9e3d600 fix: uncaught type error while logging (#277) 2021-07-07 14:28:42 -05:00
phil-ociraptor
361569ac2f chore: emit a log when a quote is returned that is between 99-100% of quote (#275) 2021-07-06 17:19:41 -05:00
Github Actions
719664c145 Publish
- @0x/contracts-integrations@2.7.57
 - @0x/asset-swapper@16.20.0
2021-07-06 21:34:44 +00:00
Github Actions
f800d6c24c Updated CHANGELOGS & MD docs 2021-07-06 21:34:39 +00:00
Romain Butteaud
a9a81bcafb feat: ShibaSwap (#276) 2021-07-06 13:53:39 -07:00
Github Actions
4280307a15 Publish
- @0x/contracts-integrations@2.7.56
 - @0x/asset-swapper@16.19.1
2021-07-06 04:03:16 +00:00
Github Actions
7b57d3ae51 Updated CHANGELOGS & MD docs 2021-07-06 04:03:11 +00:00
Romain Butteaud
8a8a5bbda0 fix: adding MultiHop for Polygon (#271) 2021-07-06 13:33:41 +10:00
Jacob Evans
76987c8db1 fix: PLP fallback (#272)
* fix: PLP fallback

* CHANGELOG
2021-07-06 13:32:34 +10:00
Github Actions
6f8971cc42 Publish
- @0x/contracts-integrations@2.7.55
 - @0x/asset-swapper@16.19.0
2021-07-02 01:48:13 +00:00
Github Actions
71ab882143 Updated CHANGELOGS & MD docs 2021-07-02 01:48:08 +00:00
Romain Butteaud
5a4961c8d9 fix: KyberDMM pick best pools, Polygon KyberDMM (#269)
* fix: KyberDMM all pools, Polygon KyberDMM

* fix: KyberDMM, remove getPoolsLength interface and revert if no pools found
2021-07-01 18:07:02 -07:00
mzhu25
4c4fb99d87 Add PLP as a source for Polygon (#270)
* Whitelist PLP as a source for Polygon

* changelog
2021-07-01 17:21:23 -07:00
Github Actions
872abf09e9 Publish
- @0x/contracts-integrations@2.7.54
 - @0x/asset-swapper@6.18.3
2021-06-29 17:20:15 +00:00
Github Actions
f10bfe7d04 Updated CHANGELOGS & MD docs 2021-06-29 17:20:11 +00:00
Romain Butteaud
a74d8deff3 feat: Balancer V2 Polygon (#267) 2021-06-29 09:46:17 -07:00
Github Actions
835ee4e8de Publish
- @0x/contracts-integrations@2.7.53
 - @0x/asset-swapper@6.18.2
2021-06-24 19:25:12 +00:00
Github Actions
63ec42303f Updated CHANGELOGS & MD docs 2021-06-24 19:25:07 +00:00
Romain Butteaud
f789aebddc fix: duplicate SOURCE_FLAGS index (#266) 2021-06-24 11:58:05 -07:00
Github Actions
efd83be779 Publish
- @0x/contracts-integrations@2.7.52
 - @0x/asset-swapper@6.18.1
2021-06-22 23:37:28 +00:00
Github Actions
603bc1d51c Updated CHANGELOGS & MD docs 2021-06-22 23:37:23 +00:00
Romain Butteaud
32a930a7fc feat: FirebirdOneSwap, ApeSwap [TKR-182] [TKR-173] (#265)
* fix: removing TITAN and IRON as intermediate tokens

* feat: FirebirdOneSwap, ApeSwap, intermediate tokens update

* chore: changelog
2021-06-22 16:04:09 -07:00
Github Actions
f464bf68d7 Publish
- @0x/contracts-asset-proxy@3.7.16
 - @0x/contracts-broker@1.1.34
 - @0x/contracts-coordinator@3.1.35
 - @0x/contracts-dev-utils@1.3.33
 - @0x/contracts-erc1155@2.1.34
 - @0x/contracts-erc20@3.3.13
 - @0x/contracts-erc721@3.1.34
 - @0x/contracts-exchange-forwarder@4.2.35
 - @0x/contracts-exchange-libs@4.3.34
 - @0x/contracts-exchange@3.2.35
 - @0x/contracts-extensions@6.2.29
 - @0x/contracts-integrations@2.7.51
 - @0x/contracts-multisig@4.1.35
 - @0x/contracts-staking@2.0.42
 - @0x/contracts-test-utils@5.4.5
 - @0x/contracts-treasury@1.2.3
 - @0x/contracts-utils@4.7.13
 - @0x/contracts-zero-ex@0.26.0
 - @0x/asset-swapper@6.18.0
 - @0x/contract-addresses@6.4.0
 - @0x/contract-wrappers-test@12.2.50
 - @0x/contract-wrappers@13.17.2
 - @0x/migrations@8.0.11
 - @0x/order-utils@10.4.26
 - @0x/protocol-utils@1.7.2
2021-06-22 10:03:41 +00:00
Github Actions
ebdc4fb509 Updated CHANGELOGS & MD docs 2021-06-22 10:03:35 +00:00
Kim Persson
7580719586 feat: Lido StETH deposit integration [TKR-90] (#260)
* feat: initial stab at the LidoSampler and the MixinLido

* feat: full integration of lido sampler and mixin

* fix: return pooled Ether amount not shares & properly unwrap WETH

* refactor: clean up Lido sampler and data passing

* fix: lower gas schedule for WETH to stETH deposits

* refactor: remove MixinLido unused ETH code path

* chore: add changelog entries

* fix: lower Lido gas schedule slightly

* fix: revert MixinLido on unsupported token pair

* fix: address review comments, improve early exit if wrong tokens

* fix: add contract addresses to Lido FQT
2021-06-22 11:25:47 +02:00
Github Actions
aba9db2be7 Publish
- @0x/contracts-integrations@2.7.50
 - @0x/asset-swapper@6.17.3
2021-06-16 01:38:55 +00:00
Github Actions
a6680411c8 Updated CHANGELOGS & MD docs 2021-06-16 01:38:51 +00:00
Romain Butteaud
0d0e87de94 QUICK, TITAN, IRON as intermediate tokens, integrating WaultSwap and Polydex for Polygon, Curve renBTC pool (#264) 2021-06-15 18:12:07 -07:00
Github Actions
ccf2000c09 Publish
- @0x/contracts-asset-proxy@3.7.15
 - @0x/contracts-broker@1.1.33
 - @0x/contracts-coordinator@3.1.34
 - @0x/contracts-dev-utils@1.3.32
 - @0x/contracts-erc1155@2.1.33
 - @0x/contracts-erc20@3.3.12
 - @0x/contracts-erc721@3.1.33
 - @0x/contracts-exchange-forwarder@4.2.34
 - @0x/contracts-exchange-libs@4.3.33
 - @0x/contracts-exchange@3.2.34
 - @0x/contracts-extensions@6.2.28
 - @0x/contracts-integrations@2.7.49
 - @0x/contracts-multisig@4.1.34
 - @0x/contracts-staking@2.0.41
 - @0x/contracts-test-utils@5.4.4
 - @0x/contracts-treasury@1.2.2
 - @0x/contracts-utils@4.7.12
 - @0x/contracts-zero-ex@0.25.1
 - @0x/asset-swapper@6.17.2
 - @0x/contract-addresses@6.3.1
 - @0x/contract-wrappers-test@12.2.49
 - @0x/contract-wrappers@13.17.1
 - @0x/migrations@8.0.10
 - @0x/order-utils@10.4.25
 - @0x/protocol-utils@1.7.1
2021-06-11 03:34:49 +00:00
Github Actions
3eb2e0f56a Updated CHANGELOGS & MD docs 2021-06-11 03:34:44 +00:00
Romain Butteaud
d07c7d5b69 feat: Curve V2 (#262)
* feat: Curve V2

* fix: CurveV2 gas schedule, remove unused import from MixinCurveV2

* feat: FQT address update

* chore: Curve V2 exchange_underlying, adding Polygon atricrypto pool

* prettier

* feat: FQT Polygon address update

* feat: FQT address update
2021-06-10 19:01:11 -07:00
Romain Butteaud
adf6684c29 chore: adding Uni v3 as a fee source (#261) 2021-06-08 17:57:49 -07:00
Github Actions
9bf889aa30 Publish
- @0x/contracts-asset-proxy@3.7.14
 - @0x/contracts-broker@1.1.32
 - @0x/contracts-coordinator@3.1.33
 - @0x/contracts-dev-utils@1.3.31
 - @0x/contracts-erc1155@2.1.32
 - @0x/contracts-erc20@3.3.11
 - @0x/contracts-erc721@3.1.32
 - @0x/contracts-exchange-forwarder@4.2.33
 - @0x/contracts-exchange-libs@4.3.32
 - @0x/contracts-exchange@3.2.33
 - @0x/contracts-extensions@6.2.27
 - @0x/contracts-integrations@2.7.48
 - @0x/contracts-multisig@4.1.33
 - @0x/contracts-staking@2.0.40
 - @0x/contracts-test-utils@5.4.3
 - @0x/contracts-treasury@1.2.1
 - @0x/contracts-utils@4.7.11
 - @0x/contracts-zero-ex@0.25.0
 - @0x/asset-swapper@6.17.1
 - @0x/contract-artifacts@3.15.0
 - @0x/contract-wrappers-test@12.2.48
 - @0x/contract-wrappers@13.17.0
 - @0x/migrations@8.0.9
 - @0x/order-utils@10.4.24
 - @0x/protocol-utils@1.7.0
2021-06-02 04:53:54 +00:00
Github Actions
e81c88564e Updated CHANGELOGS & MD docs 2021-06-02 04:53:49 +00:00
Lawrence Forman
901d400d62 Address spot check feedback (#251)
* UniswapV3 VIP (#237)

* `@0x/contracts-zero-ex`: Add UniswapV3Feature

* `@0x/contracts-zero-ex`: Add UniswapV3 VIP
`@0x/contract-artifacts`: Regenerate.
`@0x/contract-wrappers`: Regenerate.
`@0x/asset-swapper`: Add UniswapV3 VIP support.

* address review comments and appease linter

* `@0x/contracts-zero-ex`: Add UniswapV3Feature tests

* Multiplex UniswapV3 (#241)

* Add UniswapV3 support to Multiplex batchFill

* Add AssetSwapper support for Multiplex UniswapV3

* fix repo scripts that use PKG= env var (#242)

Co-authored-by: Lawrence Forman <me@merklejerk.com>

* `@0x/asset-swapper`: Adjust uniswap gas overhead

Co-authored-by: Lawrence Forman <me@merklejerk.com>
Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com>

* OTC orders feature (#244)

* Add OTC orders feature contracts

* Address PR feedback

* Remove partial fills for takerSigned variant

* Add function to query the min valid nonce

* Add ETH support

* Tightly pack expiry, nonceBucket, and nonce

* Address PR feedback

* OTC orders unit tests

* Bump prettier version

* Skip unnecessary math if takerTokenFillAmount == order.takerAmount

* appease CI

* Update contract-artifacts and contract-wrappers and CHANGELOGs

* `@0x/contracts-zero-ex`: Address spot check feedback

* `regen wrappers

* prettier

* `@0x/asset-swapper`: prettier and tweak gas schedule slightly for uni3

Co-authored-by: Lawrence Forman <me@merklejerk.com>
Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com>
2021-06-02 14:21:14 +10:00
Github Actions
289474e2ce Publish
- @0x/contracts-integrations@2.7.47
 - @0x/contracts-treasury@1.2.0
 - @0x/asset-swapper@6.17.0
2021-05-27 22:22:14 +00:00
Github Actions
407ca21168 Updated CHANGELOGS & MD docs 2021-05-27 22:22:09 +00:00
mzhu25
5c68fc24d2 Miscellaneous Liquidity Provider changes (#253)
* Update KNC address and reenable PLP

* Enable PLP VIP on BSC
2021-05-25 14:01:07 -07:00
mzhu25
548800e0a9 Add proposal 0 params and mainnet fork test (#252) 2021-05-25 13:48:34 -07:00
Github Actions
bde3d6dc6a Publish
- @0x/contracts-asset-proxy@3.7.13
 - @0x/contracts-broker@1.1.31
 - @0x/contracts-coordinator@3.1.32
 - @0x/contracts-dev-utils@1.3.30
 - @0x/contracts-erc1155@2.1.31
 - @0x/contracts-erc20@3.3.10
 - @0x/contracts-erc721@3.1.31
 - @0x/contracts-exchange-forwarder@4.2.32
 - @0x/contracts-exchange-libs@4.3.31
 - @0x/contracts-exchange@3.2.32
 - @0x/contracts-extensions@6.2.26
 - @0x/contracts-integrations@2.7.46
 - @0x/contracts-multisig@4.1.32
 - @0x/contracts-staking@2.0.39
 - @0x/contracts-test-utils@5.4.2
 - @0x/contracts-treasury@1.1.8
 - @0x/contracts-utils@4.7.10
 - @0x/contracts-zero-ex@0.24.1
 - @0x/asset-swapper@6.16.0
 - @0x/contract-addresses@6.3.0
 - @0x/contract-wrappers-test@12.2.47
 - @0x/contract-wrappers@13.16.3
 - @0x/migrations@8.0.8
 - @0x/order-utils@10.4.23
 - @0x/protocol-utils@1.6.2
2021-05-25 12:13:43 +00:00
Github Actions
56550a6acc Updated CHANGELOGS & MD docs 2021-05-25 12:13:38 +00:00
Kim Persson
e51b83accc Polygon support (#240)
* feat: Polygon deployed

* Updated polygon FQT address

* feat: add SushiSwap on Polygon WIP

* fix: add Matic as a native token

* refactor: import valueByChainId from token-metadata to consolidate impl

* refactor: use same gas schedule fn for all uni v2 clones

* feat: Add QuickSwap Polygon integration

* fix: add Polygon tokens to initial TokenAdjacencyGraph

* feat: ComethSwap Polygon integration

* feat: Add Curve, Dfyn, mStable for Polygon

* fix: temporarily private publish contract-addresses, token-metadata

* feat: Add DODO V2 support for polygon, stability pool on mainnet, bsc

* chore: fix linting

* fix: incorrect Curve Polygon gas schedule

Co-authored-by: Jacob Evans <jacob@dekz.net>

* refator: consolidate Polygon token addresses in POLYGON_TOKENS

* feat: Polygon DODO V1 integration

* fix: remove dependency on @0x/token-metadata

* chore: remove private publish dependencies and add changelog entry

Co-authored-by: Jacob Evans <jacob@dekz.net>
Co-authored-by: Romain Butteaud <romain.butteaud@gmail.com>
2021-05-25 13:40:52 +02:00
Github Actions
d5ae971f1c Publish
- @0x/contracts-asset-proxy@3.7.12
 - @0x/contracts-broker@1.1.30
 - @0x/contracts-coordinator@3.1.31
 - @0x/contracts-dev-utils@1.3.29
 - @0x/contracts-erc1155@2.1.30
 - @0x/contracts-erc20@3.3.9
 - @0x/contracts-erc721@3.1.30
 - @0x/contracts-exchange-forwarder@4.2.31
 - @0x/contracts-exchange-libs@4.3.30
 - @0x/contracts-exchange@3.2.31
 - @0x/contracts-extensions@6.2.25
 - @0x/contracts-integrations@2.7.45
 - @0x/contracts-multisig@4.1.31
 - @0x/contracts-staking@2.0.38
 - @0x/contracts-test-utils@5.4.1
 - @0x/contracts-treasury@1.1.7
 - @0x/contracts-utils@4.7.9
 - @0x/contracts-zero-ex@0.24.0
 - @0x/asset-swapper@6.15.0
 - @0x/contract-addresses@6.2.0
 - @0x/contract-wrappers-test@12.2.46
 - @0x/contract-wrappers@13.16.2
 - @0x/migrations@8.0.7
 - @0x/order-utils@10.4.22
 - @0x/protocol-utils@1.6.1
2021-05-21 12:37:26 +00:00
Github Actions
5a2f5f9a42 Updated CHANGELOGS & MD docs 2021-05-21 12:37:22 +00:00
Jacob Evans
75a3b70cef chore: Temporarily disable a LiquidityProvider (#248) 2021-05-21 22:08:55 +10:00
Jacob Evans
803cf65ba1 fix: Deploy FQT for KyberDmm/Mstable (#247) 2021-05-19 08:34:26 +10:00
Jacob Evans
5d3947b838 fix prettier 2021-05-18 09:10:29 +10:00
mzhu25
4397a59008 Add Huobi Token to liquidity provider tokens (#246) 2021-05-17 15:21:53 -07:00
Jacob Evans
966d54c935 fix: KyberDmm (#236)
* fix: KyberDmm

* fix: pass buyToken to kyberDmm and require that path ends with buyToken

* Pass BigNumber down to FastABI

* Address Feedback

Co-authored-by: Kim Persson <kimpersson88@gmail.com>
2021-05-18 08:12:28 +10:00
Romain Butteaud
234ddb495d fix: mStable USD Sampler and Mixin fix (#238)
* fix: mStable USD Sampler and Mixin fix

* chore: adding mBTC (mStable) pool

* fix linter
2021-05-16 19:43:06 -07:00
mzhu25
a744acc7bc Add special selectors to selector collision test (#243) 2021-05-14 10:50:58 -07:00
Lawrence Forman
27c624633c fix repo scripts that use PKG= env var (#242)
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2021-05-12 18:53:06 -04:00
Github Actions
7ef75101b4 Publish
- @0x/contracts-integrations@2.7.44
 - @0x/asset-swapper@6.14.0
2021-05-12 09:13:31 +00:00
Github Actions
6f8aace00d Updated CHANGELOGS & MD docs 2021-05-12 09:13:23 +00:00
Kim Persson
6c264b2f18 feat: add DAI and USDC as intermediate tokens on Ropsten [TKR-93] (#231)
* feat: add DAI and USDC as intermediate tokens on Ropsten

* chore: add changelog entry
2021-05-11 19:36:46 +02:00
Daniel Pyrathon
df055e1958 fix: Added fee parameter to Quote Requestor (#235)
* Added changes

* Fixes

* Applied PR feedback

* lint fix
2021-05-11 12:57:51 -04:00
Github Actions
70d2117470 Publish
- @0x/contracts-integrations@2.7.43
 - @0x/asset-swapper@6.13.0
2021-05-11 03:18:25 +00:00
Github Actions
2c173ccaf3 Updated CHANGELOGS & MD docs 2021-05-11 03:18:20 +00:00
mzhu25
d2f4a0c5f3 Updated config.yml 2021-05-10 19:51:12 -07:00
mzhu25
0d6021e5e3 Add LiquidityProvider to BSC sources (#234) 2021-05-10 18:27:52 -07:00
Github Actions
bb04726e7f Publish
- @0x/contracts-integrations@2.7.42
 - @0x/asset-swapper@6.12.0
2021-05-10 01:36:49 +00:00
Github Actions
220ca370c2 Updated CHANGELOGS & MD docs 2021-05-10 01:36:44 +00:00
Jacob Evans
63af4e3e98 fix: TwoHopSampler call (#233) 2021-05-10 11:05:30 +10:00
Github Actions
9754e12d82 Publish
- @0x/contracts-integrations@2.7.41
 - @0x/asset-swapper@6.11.0
2021-05-07 04:35:35 +00:00
Github Actions
d72ebed246 Updated CHANGELOGS & MD docs 2021-05-07 04:35:31 +00:00
Jacob Evans
587fc71058 fix: Sampler contract address overrides (#232)
* fix: Sampler contract address overrides

* Update CHANGELOG
2021-05-07 13:52:51 +10:00
Kim Persson
7d34e09a12 fix: add separate priceComparisonsReport to fix missing quoteReport data [TKR-91] (#219)
* fix: add separate priceComparisonsReport to fix missing quoteReport data

* chore: remove notice about unconfirmed Uniswap V3 addresses

* refactor: move price comparisons computation logic into separate method

* chore: add AS changelog entry
2021-05-06 14:54:54 +02:00
Kim Persson
7d15baad0f feat: Balancer V2 load and cache top pools by num swaps on startup [TKR-96] (#228)
* feat: Balancer V2 load and cache top pools by num swaps on startup

* refactor: Clean up code for Balancer V1 & V2 cache heating

* chore: add AS changelog entry
2021-05-06 14:21:30 +02:00
mzhu25
1e6476ada7 Add ETH pseudo-address when wrapping/unwrapping in Multiplex multihop (#230)
* Add ETH pseudo-address when wrapping/unwrapping in Multiplex multihop

* Update changelog
2021-05-06 15:29:24 +10:00
Lawrence Forman
1d6ca5f6b5 @0x/asset-swapper: Tweak compiler settings for smaller sampler size (#229)
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2021-05-05 18:36:38 -04:00
Github Actions
fb249f02fc Publish
- @0x/contracts-asset-proxy@3.7.11
 - @0x/contracts-broker@1.1.29
 - @0x/contracts-coordinator@3.1.30
 - @0x/contracts-dev-utils@1.3.28
 - @0x/contracts-erc1155@2.1.29
 - @0x/contracts-erc20@3.3.8
 - @0x/contracts-erc721@3.1.29
 - @0x/contracts-exchange-forwarder@4.2.30
 - @0x/contracts-exchange-libs@4.3.29
 - @0x/contracts-exchange@3.2.30
 - @0x/contracts-extensions@6.2.24
 - @0x/contracts-integrations@2.7.40
 - @0x/contracts-multisig@4.1.30
 - @0x/contracts-staking@2.0.37
 - @0x/contracts-test-utils@5.4.0
 - @0x/contracts-treasury@1.1.6
 - @0x/contracts-utils@4.7.8
 - @0x/contracts-zero-ex@0.23.0
 - @0x/asset-swapper@6.10.0
 - @0x/contract-addresses@6.1.0
 - @0x/contract-artifacts@3.14.2
 - @0x/contract-wrappers-test@12.2.45
 - @0x/contract-wrappers@13.16.1
 - @0x/migrations@8.0.6
 - @0x/order-utils@10.4.21
 - @0x/protocol-utils@1.6.0
2021-05-05 11:32:51 +00:00
Github Actions
fdf04ef275 Updated CHANGELOGS & MD docs 2021-05-05 11:32:46 +00:00
Jacob Evans
b0f5f634f2 bump test-publish resource_class 2021-05-05 21:02:31 +10:00
Jacob Evans
6ee0108565 fix: async pool cache (#226) 2021-05-05 21:01:51 +10:00
Jacob Evans
c73097e688 chore: Deploy FQT with UniswapV3 support (#227) 2021-05-05 21:01:39 +10:00
Lawrence Forman
a2d42b07b5 UniswapV3 [TKR-4] (#197)
* add balancer v2

* fetch balancer v2 pools from subgraph

* feat: initial stab at a Balancer V2 Sampler WIP

* feat: add sampling for buys and fix build issues WIP [untested]

* fix: BalancerV2Sampler implementation issues, works on Kovan

* chore: BalancerV2 sampling boilerplate

* fix: update Balancer V2 mainnet address

* fix: consolidate differences between the 2 working branches

* fix: use mainnet Balancer V2 subgraph

* fix: stack too deep by minimizing and inline Balancer V2 vault interface

* fix: address review comments and clean up

* fix: sampler vault interface and pools cache assuming a pool has swaps

* address more review comments

* fix: TS type issues and add a comment about deadline argument

* fix: pools_cache_tests incorrect token addresses, prettier incompat

* fix: make ERC20BridgeSampler support BalancerV2 non view sampler fns

* fix: use a struct for passing encoded bridge data for Balancer V2

* chore: add changelog entries

* fix: improve gas accuracy of gas schedule for Balancer V2 & Maker Psm

* fix: don't exclude sources with stale caches & wait for cache refresh

* rebase

* `@0x/asset-swapper`: Fix stack too deep errors in sampler

* `@0x/asset-swapper`: Add uniswap V3 sampler.

* `@0x/contracts-zero-ex`: Add UniswapV3 support to FQT

* `@0x/protocol-utils`: Update BridgeProtocols.
`@0x/asset-swapper`: Add sell integration for UniswapV3.

* `@0x/asset-swapper`: Remove unnecessary swap quote consumer constructor arg.
`@0x/asset-swapper`: Enable UniswapV3 on ropsten.

* `@0x/asset-swapper`: UniswapV3 fixes

* `@0x/asset-swapper`: Fix stuff based on latest deployed testnet contracts

* `@0x/asset-swapper`: Remove UniV3 from mainnet sources for now

* `@0x/asset-swapper`: Tweak univ3 gas schedule

* fix CI?

* `@0x/contracts-test-utils`: Set default ganache gas limit to 100e6

Co-authored-by: xianny <xianny@gmail.com>
Co-authored-by: Kim Persson <kimpersson88@gmail.com>
Co-authored-by: Lawrence Forman <me@merklejerk.com>
Co-authored-by: Jacob Evans <jacob@dekz.net>
2021-05-05 19:44:17 +10:00
Xianny
f9a794af93 feat: Balancer V2 integration (#206)
* add balancer v2

* fetch balancer v2 pools from subgraph

* feat: initial stab at a Balancer V2 Sampler WIP

* feat: add sampling for buys and fix build issues WIP [untested]

* fix: BalancerV2Sampler implementation issues, works on Kovan

* chore: BalancerV2 sampling boilerplate

* fix: update Balancer V2 mainnet address

* fix: consolidate differences between the 2 working branches

* fix: use mainnet Balancer V2 subgraph

* fix: stack too deep by minimizing and inline Balancer V2 vault interface

* fix: address review comments and clean up

* fix: sampler vault interface and pools cache assuming a pool has swaps

* address more review comments

* fix: TS type issues and add a comment about deadline argument

* fix: pools_cache_tests incorrect token addresses, prettier incompat

* fix: make ERC20BridgeSampler support BalancerV2 non view sampler fns

* fix: use a struct for passing encoded bridge data for Balancer V2

* chore: add changelog entries

* fix: improve gas accuracy of gas schedule for Balancer V2 & Maker Psm

* fix: don't exclude sources with stale caches & wait for cache refresh

* rebase

* `@0x/asset-swapper`: Fix stack too deep errors in sampler

Co-authored-by: Kim Persson <kimpersson88@gmail.com>
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2021-05-05 11:01:28 +02:00
Jacob Evans
a2643674ca Fix: PLP now generates a fallback (#223)
* fix: PLP requires a fallback

* update changelog

* Fix missed source exclusion
2021-05-05 08:22:19 +10:00
Jacob Evans
c00ce9daac feat: Support ETH based Curve pools (#220)
* feat: Support ETH based Curve pools

* Disable Curve VIP for WETH trades

* feat: Support for sETH and ankrETH (Curve)

* Disable SnowSwap ETH pools

* feat: add BUSD Curve 3pool

* fix changelog

Co-authored-by: Romain Butteaud <romain.butteaud@gmail.com>
2021-05-05 07:33:41 +10:00
mzhu25
c68b5d7844 Fix/staking epoch finalization (#221)
* Patch staking and recover state in constructor

* Add ganache mainnet fork test

* Add ganache mainnet fork test

* update changelog

* hardcode last pool ID

* Separate patch contract to unbreak tests
2021-05-04 11:29:16 -07:00
Jacob Evans
09ed106d4c feat: Deployed Balancer V2 and Curve ETH support (#225) 2021-05-04 16:52:36 +10:00
Jacob Evans
a6b92fc658 fix: Fix test forever with new sources being added 2021-05-04 16:49:16 +10:00
mzhu25
4be4a1a30b Fix exchangeProxyGasOverhead used to compute fallback orders (#215)
* Fix exchangeProxyGasOverhead used to compute fallback orders

* update changelog
2021-05-04 13:41:21 +10:00
Romain Butteaud
9bede5d331 fix: reactive PancakeSwap, BakerySwap VIP on BSC (#222) 2021-05-04 13:40:57 +10:00
Romain Butteaud
b50d4aee6d Chore: adding xSigma liquidity source [TKR-59] (#201)
* Chore: adding xSigma liquidity source

* fix: prettier
2021-05-03 19:50:26 -07:00
Jacob Evans
55bc367bd6 feat: Add LUSD Curve pool (#218) 2021-05-04 08:08:27 +10:00
Github Actions
7a59b7eafe Publish
- @0x/contracts-integrations@2.7.39
 - @0x/contracts-zero-ex@0.22.3
 - @0x/asset-swapper@6.9.1
 - @0x/contract-wrappers-test@12.2.44
 - @0x/migrations@8.0.5
2021-05-01 01:03:24 +00:00
Github Actions
9e59d41e44 Updated CHANGELOGS & MD docs 2021-05-01 01:03:19 +00:00
Jacob Evans
475e6c7bca fix: Temporarily remove PancakeV2/Bakery from VIP (#217) 2021-05-01 10:35:54 +10:00
Github Actions
dbc5a5293e Publish
- @0x/contracts-integrations@2.7.38
 - @0x/contracts-treasury@1.1.5
 - @0x/contracts-zero-ex@0.22.2
 - @0x/asset-swapper@6.9.0
 - @0x/contract-wrappers-test@12.2.43
 - @0x/migrations@8.0.4
2021-04-30 23:39:46 +00:00
Github Actions
f4bd2bd0d8 Updated CHANGELOGS & MD docs 2021-04-30 23:39:42 +00:00
Romain Butteaud
f1782a83ba chore: BSC PancakeSwap forks VIP, PancakeSwapV2, Saddle BTC pool, Curve gas schedule [TKR-41] [TKR-11] [TKR-79] [TKR-86] (#208)
* chore: popular BSC Uniswap clones, Curve gas schedule update, Saddle BTC pool

* chore: adding PancakeSwapV2 VIP

* fix: yarn prettier
2021-05-01 08:48:10 +10:00
Jacob Evans
cbade0d558 fix: Ban colliding Kyber reserve (#216) 2021-04-29 15:24:39 +10:00
mzhu25
fe0c26387c Fix treasury voting power calculation (#214)
* Fix treasury voting power calculation

* Update changelog
2021-04-28 10:22:52 -07:00
275 changed files with 19541 additions and 4204 deletions

View File

@@ -1,25 +1,25 @@
version: 2
version: 2.1
jobs:
build:
resource_class: medium+
resource_class: xlarge
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
environment:
CONTRACTS_COMMIT_HASH: '9ed05f5'
NODE_OPTIONS: '--max-old-space-size=16384'
working_directory: ~/repo
steps:
- checkout
- run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
- run:
name: install-yarn
command: npm install --force --global yarn@1.17.0
command: npm install --force --global yarn@1.22.0
- run:
name: yarn
command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
- setup_remote_docker
- run: yarn build:ci
- run: yarn build:ts
- run: yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci
- run: yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts
- save_cache:
key: repo-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -31,57 +31,59 @@ jobs:
test-exchange-ganache:
resource_class: medium+
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-exchange
- run: yarn wsrun -p @0x/contracts-exchange -m --serial -c test:circleci
test-integrations-ganache:
resource_class: medium+
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-integrations
- run: yarn wsrun -p @0x/contracts-integrations -m --serial -c test:circleci
test-contracts-staking-ganache:
resource_class: medium+
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-staking
- run: yarn wsrun -p @0x/contracts-staking -m --serial -c test:circleci
test-contracts-extra-ganache:
resource_class: medium+
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-exchange-forwarder @0x/contracts-coordinator
- run: yarn wsrun -p @0x/contracts-exchange-forwarder -p @0x/contracts-coordinator -m --serial -c test:circleci
test-contracts-rest-ganache:
resource_class: medium+
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
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
- run: yarn wsrun -p @0x/contracts-multisig -p @0x/contracts-utils -p @0x/contracts-exchange-libs -p @0x/contracts-erc20 -p @0x/contracts-erc721 -p @0x/contracts-erc1155 -p @0x/contracts-asset-proxy -p @0x/contracts-broker -p @0x/contracts-zero-ex -m --serial -c test:circleci
test-publish:
resource_class: medium+
resource_class: large
environment:
NODE_OPTIONS: '--max-old-space-size=6442'
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
- image: 0xorg/verdaccio
working_directory: ~/repo
steps:
@@ -95,7 +97,7 @@ jobs:
path: ~/.npm/_logs
test-doc-generation:
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
working_directory: ~/repo
steps:
- restore_cache:
@@ -106,18 +108,18 @@ jobs:
no_output_timeout: 1200
test-rest:
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
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/contract-artifacts
- run: yarn wsrun test:circleci @0x/contract-wrappers-test
- run: yarn wsrun test:circleci @0x/migrations
- run: yarn wsrun test:circleci @0x/order-utils
- run: yarn wsrun test:circleci @0x/asset-swapper
- run: yarn wsrun -p @0x/contracts-test-utils -m --serial -c test:circleci
- run: yarn wsrun -p @0x/contract-artifacts -m --serial -c test:circleci
- run: yarn wsrun -p @0x/contract-wrappers-test -m --serial -c test:circleci
- run: yarn wsrun -p @0x/migrations -m --serial -c test:circleci
- run: yarn wsrun -p @0x/order-utils -m --serial -c test:circleci
- run: yarn wsrun -p @0x/asset-swapper -m --serial -c test:circleci
- save_cache:
key: coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -134,7 +136,7 @@ jobs:
resource_class: large
working_directory: ~/repo
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
steps:
- restore_cache:
keys:
@@ -145,7 +147,7 @@ jobs:
- run: yarn diff_md_docs:ci
submit-coverage:
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs10
- image: node:12
working_directory: ~/repo
steps:
- restore_cache:

View File

@@ -3,5 +3,6 @@
"tabWidth": 4,
"singleQuote": true,
"trailingComma": "all",
"bracketSpacing": true
"bracketSpacing": true,
"arrowParens": "avoid"
}

View File

@@ -49,7 +49,6 @@
| Package | Version |
| ------: | :------ |
<!-- For example:
| `0x.js` | 2.0.4 |
| `Exchange Contract` | v2 |

View File

@@ -43,12 +43,12 @@ These packages are all under development. See [/contracts/README.md](/contracts/
#### 0x-specific packages
| Package | Version | Description |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| [`@0x/contract-addresses`](/packages/contract-addresses) | [![npm](https://img.shields.io/npm/v/@0x/contract-addresses.svg)](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) | [![npm](https://img.shields.io/npm/v/@0x/contract-wrappers.svg)](https://www.npmjs.com/package/@0x/contract-wrappers) | JS/TS wrappers for interacting with the 0x smart contracts |
| [`@0x/order-utils`](/packages/order-utils) | [![npm](https://img.shields.io/npm/v/@0x/order-utils.svg)](https://www.npmjs.com/package/@0x/order-utils) | A set of utilities for generating, parsing, signing and validating 0x orders |
| [`@0x/migrations`](/packages/migrations) | [![npm](https://img.shields.io/npm/v/@0x/migrations.svg)](https://www.npmjs.com/package/@0x/migrations) | Migration tool for deploying 0x smart contracts on private testnets |
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [![npm](https://img.shields.io/npm/v/@0x/contract-artifacts.svg)](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts | |
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [![npm](https://img.shields.io/npm/v/@0x/contract-artifacts.svg)](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts | |
## Usage

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "3.7.19",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "3.7.18",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "3.7.17",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "3.7.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "3.7.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "3.7.14",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "3.7.13",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "3.7.12",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "3.7.11",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "3.7.10",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.7.19 - _August 16, 2021_
* Dependencies updated
## v3.7.18 - _August 11, 2021_
* Dependencies updated
## v3.7.17 - _August 6, 2021_
* Dependencies updated
## v3.7.16 - _June 22, 2021_
* Dependencies updated
## v3.7.15 - _June 11, 2021_
* Dependencies updated
## v3.7.14 - _June 2, 2021_
* Dependencies updated
## v3.7.13 - _May 25, 2021_
* Dependencies updated
## v3.7.12 - _May 21, 2021_
* Dependencies updated
## v3.7.11 - _May 5, 2021_
* Dependencies updated
## v3.7.10 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-asset-proxy",
"version": "3.7.10",
"version": "3.7.19",
"engines": {
"node": ">=6.12"
},
@@ -51,13 +51,13 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contract-wrappers": "^13.16.0",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/contracts-utils": "^4.7.7",
"@0x/dev-utils": "^4.2.6",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contract-wrappers": "^13.17.4",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/contracts-utils": "^4.7.16",
"@0x/dev-utils": "^4.2.7",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@types/lodash": "4.14.104",
@@ -79,16 +79,16 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/contracts-erc1155": "^2.1.28",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-erc721": "^3.1.28",
"@0x/contracts-exchange-libs": "^4.3.28",
"@0x/order-utils": "^10.4.20",
"@0x/base-contract": "^6.4.0",
"@0x/contracts-erc1155": "^2.1.37",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-erc721": "^3.1.37",
"@0x/contracts-exchange-libs": "^4.3.37",
"@0x/order-utils": "^10.4.28",
"@0x/types": "^3.3.3",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/web3-wrapper": "^7.5.2",
"@0x/utils": "^6.4.3",
"@0x/web3-wrapper": "^7.5.3",
"ethereum-types": "^3.5.0",
"lodash": "^4.17.11"
},

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "1.1.37",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "1.1.36",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "1.1.35",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "1.1.34",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "1.1.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "1.1.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "1.1.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "1.1.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "1.1.29",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "1.1.28",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v1.1.37 - _August 16, 2021_
* Dependencies updated
## v1.1.36 - _August 11, 2021_
* Dependencies updated
## v1.1.35 - _August 6, 2021_
* Dependencies updated
## v1.1.34 - _June 22, 2021_
* Dependencies updated
## v1.1.33 - _June 11, 2021_
* Dependencies updated
## v1.1.32 - _June 2, 2021_
* Dependencies updated
## v1.1.31 - _May 25, 2021_
* Dependencies updated
## v1.1.30 - _May 21, 2021_
* Dependencies updated
## v1.1.29 - _May 5, 2021_
* Dependencies updated
## v1.1.28 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-broker",
"version": "1.1.28",
"version": "1.1.37",
"engines": {
"node": ">=6.12"
},
@@ -51,20 +51,20 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-asset-proxy": "^3.7.10",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-erc721": "^3.1.28",
"@0x/contracts-exchange": "^3.2.29",
"@0x/contracts-exchange-libs": "^4.3.28",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/contracts-utils": "^4.7.7",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-erc721": "^3.1.37",
"@0x/contracts-exchange": "^3.2.38",
"@0x/contracts-exchange-libs": "^4.3.37",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/contracts-utils": "^4.7.16",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
"@0x/web3-wrapper": "^7.5.2",
"@0x/web3-wrapper": "^7.5.3",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -84,10 +84,10 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/order-utils": "^10.4.20",
"@0x/base-contract": "^6.4.0",
"@0x/order-utils": "^10.4.28",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/utils": "^6.4.3",
"ethereum-types": "^3.5.0"
},
"publishConfig": {

View File

@@ -7,7 +7,10 @@ export interface GodsUnchainedProperties {
quality: BigNumber | number;
}
const propertyDataEncoder = AbiEncoder.create([{ name: 'proto', type: 'uint16' }, { name: 'quality', type: 'uint8' }]);
const propertyDataEncoder = AbiEncoder.create([
{ name: 'proto', type: 'uint16' },
{ name: 'quality', type: 'uint8' },
]);
const brokerDataEncoder = AbiEncoder.create([
{ name: 'godsUnchainedAddress', type: 'address' },
{ name: 'validatorAddress', type: 'address' },

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "3.1.38",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "3.1.37",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "3.1.36",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "3.1.35",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "3.1.34",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "3.1.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "3.1.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "3.1.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "3.1.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "3.1.29",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.1.38 - _August 16, 2021_
* Dependencies updated
## v3.1.37 - _August 11, 2021_
* Dependencies updated
## v3.1.36 - _August 6, 2021_
* Dependencies updated
## v3.1.35 - _June 22, 2021_
* Dependencies updated
## v3.1.34 - _June 11, 2021_
* Dependencies updated
## v3.1.33 - _June 2, 2021_
* Dependencies updated
## v3.1.32 - _May 25, 2021_
* Dependencies updated
## v3.1.31 - _May 21, 2021_
* Dependencies updated
## v3.1.30 - _May 5, 2021_
* Dependencies updated
## v3.1.29 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-coordinator",
"version": "3.1.29",
"version": "3.1.38",
"engines": {
"node": ">=6.12"
},
@@ -52,17 +52,17 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-asset-proxy": "^3.7.10",
"@0x/contracts-dev-utils": "^1.3.27",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-gen": "^2.0.37",
"@0x/dev-utils": "^4.2.6",
"@0x/order-utils": "^10.4.20",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-dev-utils": "^1.3.36",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-gen": "^2.0.38",
"@0x/dev-utils": "^4.2.7",
"@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/web3-wrapper": "^7.5.2",
"@0x/web3-wrapper": "^7.5.3",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -82,16 +82,16 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/assert": "^3.0.26",
"@0x/base-contract": "^6.3.2",
"@0x/contract-addresses": "^6.0.0",
"@0x/contracts-exchange": "^3.2.29",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/contracts-utils": "^4.7.7",
"@0x/json-schemas": "^6.1.2",
"@0x/assert": "^3.0.27",
"@0x/base-contract": "^6.4.0",
"@0x/contract-addresses": "^6.6.0",
"@0x/contracts-exchange": "^3.2.38",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/contracts-utils": "^4.7.16",
"@0x/json-schemas": "^6.1.3",
"@0x/types": "^3.3.3",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/utils": "^6.4.3",
"ethereum-types": "^3.5.0",
"http-status-codes": "^1.3.2"
},

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "1.3.36",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "1.3.35",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "1.3.34",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "1.3.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "1.3.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "1.3.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "1.3.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "1.3.29",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "1.3.28",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "1.3.27",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v1.3.36 - _August 16, 2021_
* Dependencies updated
## v1.3.35 - _August 11, 2021_
* Dependencies updated
## v1.3.34 - _August 6, 2021_
* Dependencies updated
## v1.3.33 - _June 22, 2021_
* Dependencies updated
## v1.3.32 - _June 11, 2021_
* Dependencies updated
## v1.3.31 - _June 2, 2021_
* Dependencies updated
## v1.3.30 - _May 25, 2021_
* Dependencies updated
## v1.3.29 - _May 21, 2021_
* Dependencies updated
## v1.3.28 - _May 5, 2021_
* Dependencies updated
## v1.3.27 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-dev-utils",
"version": "1.3.27",
"version": "1.3.36",
"engines": {
"node": ">=6.12"
},
@@ -41,17 +41,17 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/dev-utils",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/assert": "^3.0.26",
"@0x/contracts-asset-proxy": "^3.7.10",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/assert": "^3.0.27",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
"@0x/utils": "^6.4.2",
"@0x/utils": "^6.4.3",
"ethereum-types": "^3.5.0",
"ethers": "~4.0.4",
"npm-run-all": "^4.1.2",
@@ -63,7 +63,7 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/base-contract": "^6.4.0",
"@types/node": "12.12.54"
},
"publishConfig": {

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "2.1.37",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "2.1.36",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "2.1.35",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "2.1.34",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "2.1.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "2.1.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "2.1.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "2.1.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "2.1.29",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "2.1.28",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.1.37 - _August 16, 2021_
* Dependencies updated
## v2.1.36 - _August 11, 2021_
* Dependencies updated
## v2.1.35 - _August 6, 2021_
* Dependencies updated
## v2.1.34 - _June 22, 2021_
* Dependencies updated
## v2.1.33 - _June 11, 2021_
* Dependencies updated
## v2.1.32 - _June 2, 2021_
* Dependencies updated
## v2.1.31 - _May 25, 2021_
* Dependencies updated
## v2.1.30 - _May 21, 2021_
* Dependencies updated
## v2.1.29 - _May 5, 2021_
* Dependencies updated
## v2.1.28 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc1155",
"version": "2.1.28",
"version": "2.1.37",
"engines": {
"node": ">=6.12"
},
@@ -52,11 +52,11 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-utils": "^4.7.7",
"@0x/dev-utils": "^4.2.6",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-utils": "^4.7.16",
"@0x/dev-utils": "^4.2.7",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
@@ -80,10 +80,10 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/utils": "^6.4.2",
"@0x/web3-wrapper": "^7.5.2",
"@0x/base-contract": "^6.4.0",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/utils": "^6.4.3",
"@0x/web3-wrapper": "^7.5.3",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -1,4 +1,86 @@
[
{
"timestamp": 1629079369,
"version": "3.3.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "3.3.15",
"changes": [
{
"note": "Add ethers as a dependency",
"pr": 305
}
],
"timestamp": 1628665757
},
{
"timestamp": 1628225642,
"version": "3.3.14",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "3.3.13",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "3.3.12",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "3.3.11",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "3.3.10",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "3.3.9",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "3.3.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "3.3.7",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.3.16 - _August 16, 2021_
* Dependencies updated
## v3.3.15 - _August 11, 2021_
* Add ethers as a dependency (#305)
## v3.3.14 - _August 6, 2021_
* Dependencies updated
## v3.3.13 - _June 22, 2021_
* Dependencies updated
## v3.3.12 - _June 11, 2021_
* Dependencies updated
## v3.3.11 - _June 2, 2021_
* Dependencies updated
## v3.3.10 - _May 25, 2021_
* Dependencies updated
## v3.3.9 - _May 21, 2021_
* Dependencies updated
## v3.3.8 - _May 5, 2021_
* Dependencies updated
## v3.3.7 - _April 28, 2021_
* Dependencies updated

View File

@@ -28,7 +28,7 @@ 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.
/// Reverts if the return data is invalid 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.
@@ -49,7 +49,7 @@ library LibERC20TokenV06 {
/// @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.
/// Reverts if the return data is invalid 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.
@@ -66,7 +66,7 @@ library LibERC20TokenV06 {
}
/// @dev Calls `IERC20TokenV06(token).transfer()`.
/// Reverts if the result fails `isSuccessfulResult()` or the call reverts.
/// Reverts if the return data is invalid 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.
@@ -86,7 +86,7 @@ library LibERC20TokenV06 {
}
/// @dev Calls `IERC20TokenV06(token).transferFrom()`.
/// Reverts if the result fails `isSuccessfulResult()` or the call reverts.
/// Reverts if the return data is invalid 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
@@ -168,27 +168,6 @@ library LibERC20TokenV06 {
}
}
/// @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`.
@@ -201,9 +180,31 @@ library LibERC20TokenV06 {
private
{
(bool didSucceed, bytes memory resultData) = target.call(callData);
if (didSucceed && isSuccessfulResult(resultData)) {
// Revert if the call reverted.
if (!didSucceed) {
LibRichErrorsV06.rrevert(resultData);
}
// If we get back 0 returndata, this may be a non-standard ERC-20 that
// does not return a boolean. Check that it at least contains code.
if (resultData.length == 0) {
uint256 size;
assembly { size := extcodesize(target) }
require(size > 0, "invalid token address, contains no code");
return;
}
// If we get back at least 32 bytes, we know the target address
// contains code, and we assume it is a token that returned a boolean
// success value, which must be true.
if (resultData.length >= 32) {
uint256 result = LibBytesV06.readUint256(resultData, 0);
if (result == 1) {
return;
} else {
LibRichErrorsV06.rrevert(resultData);
}
}
// If 0 < returndatasize < 32, the target is a contract, but not a
// valid token.
LibRichErrorsV06.rrevert(resultData);
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc20",
"version": "3.3.7",
"version": "3.3.16",
"engines": {
"node": ">=6.12"
},
@@ -51,18 +51,18 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/contracts-utils": "^4.7.7",
"@0x/dev-utils": "^4.2.6",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/contracts-utils": "^4.7.16",
"@0x/dev-utils": "^4.2.7",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/web3-wrapper": "^7.5.2",
"@0x/utils": "^6.4.3",
"@0x/web3-wrapper": "^7.5.3",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -82,7 +82,8 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2"
"@0x/base-contract": "^6.4.0",
"ethers": "~4.0.4"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "3.1.37",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "3.1.36",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "3.1.35",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "3.1.34",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "3.1.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "3.1.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "3.1.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "3.1.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "3.1.29",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "3.1.28",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.1.37 - _August 16, 2021_
* Dependencies updated
## v3.1.36 - _August 11, 2021_
* Dependencies updated
## v3.1.35 - _August 6, 2021_
* Dependencies updated
## v3.1.34 - _June 22, 2021_
* Dependencies updated
## v3.1.33 - _June 11, 2021_
* Dependencies updated
## v3.1.32 - _June 2, 2021_
* Dependencies updated
## v3.1.31 - _May 25, 2021_
* Dependencies updated
## v3.1.30 - _May 21, 2021_
* Dependencies updated
## v3.1.29 - _May 5, 2021_
* Dependencies updated
## v3.1.28 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc721",
"version": "3.1.28",
"version": "3.1.37",
"engines": {
"node": ">=6.12"
},
@@ -52,18 +52,18 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/contracts-utils": "^4.7.7",
"@0x/dev-utils": "^4.2.6",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/contracts-utils": "^4.7.16",
"@0x/dev-utils": "^4.2.7",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/web3-wrapper": "^7.5.2",
"@0x/utils": "^6.4.3",
"@0x/web3-wrapper": "^7.5.3",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -84,7 +84,7 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2"
"@0x/base-contract": "^6.4.0"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "4.2.38",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "4.2.37",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "4.2.36",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "4.2.35",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "4.2.34",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "4.2.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "4.2.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "4.2.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "4.2.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "4.2.29",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.2.38 - _August 16, 2021_
* Dependencies updated
## v4.2.37 - _August 11, 2021_
* Dependencies updated
## v4.2.36 - _August 6, 2021_
* Dependencies updated
## v4.2.35 - _June 22, 2021_
* Dependencies updated
## v4.2.34 - _June 11, 2021_
* Dependencies updated
## v4.2.33 - _June 2, 2021_
* Dependencies updated
## v4.2.32 - _May 25, 2021_
* Dependencies updated
## v4.2.31 - _May 21, 2021_
* Dependencies updated
## v4.2.30 - _May 5, 2021_
* Dependencies updated
## v4.2.29 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-exchange-forwarder",
"version": "4.2.29",
"version": "4.2.38",
"engines": {
"node": ">=6.12"
},
@@ -52,25 +52,25 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-asset-proxy": "^3.7.10",
"@0x/contracts-dev-utils": "^1.3.27",
"@0x/contracts-erc1155": "^2.1.28",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-erc721": "^3.1.28",
"@0x/contracts-exchange": "^3.2.29",
"@0x/contracts-exchange-libs": "^4.3.28",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/contracts-utils": "^4.7.7",
"@0x/dev-utils": "^4.2.6",
"@0x/order-utils": "^10.4.20",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-dev-utils": "^1.3.36",
"@0x/contracts-erc1155": "^2.1.37",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-erc721": "^3.1.37",
"@0x/contracts-exchange": "^3.2.38",
"@0x/contracts-exchange-libs": "^4.3.37",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/contracts-utils": "^4.7.16",
"@0x/dev-utils": "^4.2.7",
"@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
"@0x/utils": "^6.4.2",
"@0x/web3-wrapper": "^7.5.2",
"@0x/utils": "^6.4.3",
"@0x/web3-wrapper": "^7.5.3",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -90,7 +90,7 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/base-contract": "^6.4.0",
"@0x/typescript-typings": "^5.2.0",
"ethereum-types": "^3.5.0"
},

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "4.3.37",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "4.3.36",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "4.3.35",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "4.3.34",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "4.3.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "4.3.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "4.3.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "4.3.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "4.3.29",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "4.3.28",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.3.37 - _August 16, 2021_
* Dependencies updated
## v4.3.36 - _August 11, 2021_
* Dependencies updated
## v4.3.35 - _August 6, 2021_
* Dependencies updated
## v4.3.34 - _June 22, 2021_
* Dependencies updated
## v4.3.33 - _June 11, 2021_
* Dependencies updated
## v4.3.32 - _June 2, 2021_
* Dependencies updated
## v4.3.31 - _May 25, 2021_
* Dependencies updated
## v4.3.30 - _May 21, 2021_
* Dependencies updated
## v4.3.29 - _May 5, 2021_
* Dependencies updated
## v4.3.28 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-exchange-libs",
"version": "4.3.28",
"version": "4.3.37",
"engines": {
"node": ">=6.12"
},
@@ -52,14 +52,14 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/libs",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-gen": "^2.0.37",
"@0x/dev-utils": "^4.2.6",
"@0x/sol-compiler": "^4.7.2",
"@0x/subproviders": "^6.5.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-gen": "^2.0.38",
"@0x/dev-utils": "^4.2.7",
"@0x/sol-compiler": "^4.7.3",
"@0x/subproviders": "^6.5.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/web3-wrapper": "^7.5.2",
"@0x/web3-wrapper": "^7.5.3",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -80,13 +80,13 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/contracts-utils": "^4.7.7",
"@0x/order-utils": "^10.4.20",
"@0x/base-contract": "^6.4.0",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/contracts-utils": "^4.7.16",
"@0x/order-utils": "^10.4.28",
"@0x/types": "^3.3.3",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/utils": "^6.4.3",
"ethereum-types": "^3.5.0"
},
"publishConfig": {

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "3.2.38",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "3.2.37",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "3.2.36",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "3.2.35",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "3.2.34",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "3.2.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "3.2.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "3.2.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "3.2.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "3.2.29",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.2.38 - _August 16, 2021_
* Dependencies updated
## v3.2.37 - _August 11, 2021_
* Dependencies updated
## v3.2.36 - _August 6, 2021_
* Dependencies updated
## v3.2.35 - _June 22, 2021_
* Dependencies updated
## v3.2.34 - _June 11, 2021_
* Dependencies updated
## v3.2.33 - _June 2, 2021_
* Dependencies updated
## v3.2.32 - _May 25, 2021_
* Dependencies updated
## v3.2.31 - _May 21, 2021_
* Dependencies updated
## v3.2.30 - _May 5, 2021_
* Dependencies updated
## v3.2.29 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-exchange",
"version": "3.2.29",
"version": "3.2.38",
"engines": {
"node": ">=6.12"
},
@@ -52,21 +52,21 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-asset-proxy": "^3.7.10",
"@0x/contracts-exchange-libs": "^4.3.28",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-multisig": "^4.1.29",
"@0x/contracts-staking": "^2.0.36",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/contracts-utils": "^4.7.7",
"@0x/dev-utils": "^4.2.6",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-exchange-libs": "^4.3.37",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-multisig": "^4.1.38",
"@0x/contracts-staking": "^2.0.45",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/contracts-utils": "^4.7.16",
"@0x/dev-utils": "^4.2.7",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
"@0x/typescript-typings": "^5.2.0",
"@0x/web3-wrapper": "^7.5.2",
"@0x/web3-wrapper": "^7.5.3",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -88,13 +88,13 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/contracts-dev-utils": "^1.3.27",
"@0x/contracts-erc1155": "^2.1.28",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-erc721": "^3.1.28",
"@0x/order-utils": "^10.4.20",
"@0x/utils": "^6.4.2",
"@0x/base-contract": "^6.4.0",
"@0x/contracts-dev-utils": "^1.3.36",
"@0x/contracts-erc1155": "^2.1.37",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-erc721": "^3.1.37",
"@0x/order-utils": "^10.4.28",
"@0x/utils": "^6.4.3",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -13,7 +13,11 @@ export const exchangeDataEncoder = {
.getABIEncodedTransactionData();
} else if (constants.BATCH_FILL_FN_NAMES.indexOf(fnName) !== -1) {
data = (exchangeInstance as any)
[fnName](orders, orders.map(order => order.takerAssetAmount), orders.map(order => order.signature))
[fnName](
orders,
orders.map(order => order.takerAssetAmount),
orders.map(order => order.signature),
)
.getABIEncodedTransactionData();
} else if (constants.MARKET_FILL_FN_NAMES.indexOf(fnName) !== -1) {
const fillAsset = /Buy/.test(fnName) ? 'makerAssetAmount' : 'takerAssetAmount';

View File

@@ -39,7 +39,10 @@ blockchainTests.resets('Reentrancy Tests', env => {
// Handle tuples.
if (item.type === 'tuple') {
const tuple = item as TupleDataItem;
return _.zipObject(tuple.components.map(c => c.name), tuple.components.map(createFunctionInputs));
return _.zipObject(
tuple.components.map(c => c.name),
tuple.components.map(createFunctionInputs),
);
}
// Handle strings.
if (item.type === 'string') {

View File

@@ -109,7 +109,11 @@ export class ExchangeWrapper {
opts: { makerAssetFillAmount: BigNumber; gas?: number; gasPrice?: BigNumber },
): Promise<TransactionReceiptWithDecodedLogs> {
return this.exchangeContract
.marketBuyOrdersNoThrow(orders, opts.makerAssetFillAmount, orders.map(signedOrder => signedOrder.signature))
.marketBuyOrdersNoThrow(
orders,
opts.makerAssetFillAmount,
orders.map(signedOrder => signedOrder.signature),
)
.awaitTransactionSuccessAsync({ from, gas: opts.gas });
}
public async marketSellOrdersFillOrKillAsync(

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "6.2.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "6.2.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "6.2.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "6.2.29",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "6.2.28",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "6.2.27",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "6.2.26",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "6.2.25",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "6.2.24",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "6.2.23",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v6.2.32 - _August 16, 2021_
* Dependencies updated
## v6.2.31 - _August 11, 2021_
* Dependencies updated
## v6.2.30 - _August 6, 2021_
* Dependencies updated
## v6.2.29 - _June 22, 2021_
* Dependencies updated
## v6.2.28 - _June 11, 2021_
* Dependencies updated
## v6.2.27 - _June 2, 2021_
* Dependencies updated
## v6.2.26 - _May 25, 2021_
* Dependencies updated
## v6.2.25 - _May 21, 2021_
* Dependencies updated
## v6.2.24 - _May 5, 2021_
* Dependencies updated
## v6.2.23 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-extensions",
"version": "6.2.23",
"version": "6.2.32",
"engines": {
"node": ">=6.12"
},
@@ -52,23 +52,23 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-asset-proxy": "^3.7.10",
"@0x/contracts-dev-utils": "^1.3.27",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-erc721": "^3.1.28",
"@0x/contracts-exchange": "^3.2.29",
"@0x/contracts-exchange-libs": "^4.3.28",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-utils": "^4.7.7",
"@0x/dev-utils": "^4.2.6",
"@0x/order-utils": "^10.4.20",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-dev-utils": "^1.3.36",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-erc721": "^3.1.37",
"@0x/contracts-exchange": "^3.2.38",
"@0x/contracts-exchange-libs": "^4.3.37",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-utils": "^4.7.16",
"@0x/dev-utils": "^4.2.7",
"@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
"@0x/utils": "^6.4.2",
"@0x/web3-wrapper": "^7.5.2",
"@0x/utils": "^6.4.3",
"@0x/web3-wrapper": "^7.5.3",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -90,8 +90,8 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/base-contract": "^6.4.0",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/typescript-typings": "^5.2.0",
"ethereum-types": "^3.5.0"
},

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-integrations",
"version": "2.7.37",
"version": "2.7.64",
"private": true,
"engines": {
"node": ">=6.12"
@@ -52,25 +52,25 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contract-addresses": "^6.0.0",
"@0x/contract-wrappers": "^13.16.0",
"@0x/contracts-broker": "^1.1.28",
"@0x/contracts-coordinator": "^3.1.29",
"@0x/contracts-dev-utils": "^1.3.27",
"@0x/contracts-exchange-forwarder": "^4.2.29",
"@0x/contracts-exchange-libs": "^4.3.28",
"@0x/contracts-extensions": "^6.2.23",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-utils": "^4.7.7",
"@0x/abi-gen": "^5.6.0",
"@0x/contract-addresses": "^6.6.0",
"@0x/contract-wrappers": "^13.17.4",
"@0x/contracts-broker": "^1.1.37",
"@0x/contracts-coordinator": "^3.1.38",
"@0x/contracts-dev-utils": "^1.3.36",
"@0x/contracts-exchange-forwarder": "^4.2.38",
"@0x/contracts-exchange-libs": "^4.3.37",
"@0x/contracts-extensions": "^6.2.32",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-utils": "^4.7.16",
"@0x/coordinator-server": "^1.0.5",
"@0x/dev-utils": "^4.2.6",
"@0x/migrations": "^8.0.3",
"@0x/order-utils": "^10.4.20",
"@0x/protocol-utils": "^1.5.1",
"@0x/sol-compiler": "^4.7.2",
"@0x/dev-utils": "^4.2.7",
"@0x/migrations": "^8.1.1",
"@0x/order-utils": "^10.4.28",
"@0x/protocol-utils": "^1.8.2",
"@0x/sol-compiler": "^4.7.3",
"@0x/tslint-config": "^4.1.4",
"@0x/web3-wrapper": "^7.5.2",
"@0x/web3-wrapper": "^7.5.3",
"@azure/core-asynciterator-polyfill": "^1.0.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
@@ -93,21 +93,21 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/asset-swapper": "^6.8.0",
"@0x/base-contract": "^6.3.2",
"@0x/contracts-asset-proxy": "^3.7.10",
"@0x/contracts-erc1155": "^2.1.28",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-erc721": "^3.1.28",
"@0x/contracts-exchange": "^3.2.29",
"@0x/contracts-multisig": "^4.1.29",
"@0x/contracts-staking": "^2.0.36",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/contracts-zero-ex": "^0.22.1",
"@0x/subproviders": "^6.5.2",
"@0x/asset-swapper": "^16.25.0",
"@0x/base-contract": "^6.4.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-erc1155": "^2.1.37",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-erc721": "^3.1.37",
"@0x/contracts-exchange": "^3.2.38",
"@0x/contracts-multisig": "^4.1.38",
"@0x/contracts-staking": "^2.0.45",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/contracts-zero-ex": "^0.28.0",
"@0x/subproviders": "^6.5.3",
"@0x/types": "^3.3.3",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/utils": "^6.4.3",
"ethereum-types": "^3.5.0",
"ethereumjs-util": "^7.0.10",
"lodash": "^4.17.11"

View File

@@ -534,9 +534,14 @@ blockchainTests.skip('Coordinator Client', env => {
const signedOrders = [signedOrder, signedOrderWithDifferentFeeRecipient];
const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount];
await coordinatorClient
.batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, signedOrders.map(o => o.signature), {
from: takerAddress,
})
.batchFillOrdersAsync(
signedOrders,
takerAssetFillAmounts,
signedOrders.map(o => o.signature),
{
from: takerAddress,
},
)
.then(res => {
expect(res).to.be.undefined();
})
@@ -570,9 +575,14 @@ blockchainTests.skip('Coordinator Client', env => {
const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator];
const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount];
await coordinatorClient
.batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, signedOrders.map(o => o.signature), {
from: takerAddress,
})
.batchFillOrdersAsync(
signedOrders,
takerAssetFillAmounts,
signedOrders.map(o => o.signature),
{
from: takerAddress,
},
)
.then(res => {
expect(res).to.be.undefined();
})
@@ -600,9 +610,14 @@ blockchainTests.skip('Coordinator Client', env => {
const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator];
const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount];
await coordinatorClient
.batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, signedOrders.map(o => o.signature), {
from: takerAddress,
})
.batchFillOrdersAsync(
signedOrders,
takerAssetFillAmounts,
signedOrders.map(o => o.signature),
{
from: takerAddress,
},
)
.then(res => {
expect(res).to.be.undefined();
})

View File

@@ -267,7 +267,11 @@ blockchainTests.resets('Coordinator integration tests', env => {
expectedBalances.simulateFills(orders, taker.address, txReceipt, deployment, value);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill);
verifyEvents(
txReceipt,
orders.map(order => expectedFillEvent(order)),
ExchangeEvents.Fill,
);
});
it(`${fnName} should fill the orders if called by approver (eth fee, no refund)`, async () => {
await balanceStore.updateBalancesAsync();
@@ -280,7 +284,11 @@ blockchainTests.resets('Coordinator integration tests', env => {
expectedBalances.simulateFills(orders, taker.address, txReceipt, deployment, value);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill);
verifyEvents(
txReceipt,
orders.map(order => expectedFillEvent(order)),
ExchangeEvents.Fill,
);
});
it(`${fnName} should fill the orders if called by approver (mixed fees, refund)`, async () => {
await balanceStore.updateBalancesAsync();
@@ -293,7 +301,11 @@ blockchainTests.resets('Coordinator integration tests', env => {
expectedBalances.simulateFills(orders, taker.address, txReceipt, deployment, value);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill);
verifyEvents(
txReceipt,
orders.map(order => expectedFillEvent(order)),
ExchangeEvents.Fill,
);
});
it(`${fnName} should revert with an invalid approval signature`, async () => {
const approvalSignature = hexUtils.concat(
@@ -360,7 +372,11 @@ blockchainTests.resets('Coordinator integration tests', env => {
.executeTransaction(transaction, maker.address, transaction.signature, [])
.awaitTransactionSuccessAsync({ from: maker.address });
verifyEvents(txReceipt, orders.map(order => expectedCancelEvent(order)), ExchangeEvents.Cancel);
verifyEvents(
txReceipt,
orders.map(order => expectedCancelEvent(order)),
ExchangeEvents.Cancel,
);
});
it('cancelOrdersUpTo call should be successful without an approval', async () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrdersUpTo, []);

View File

@@ -186,13 +186,13 @@ blockchainTests.resets('LibAssetData', env => {
});
it('should decode multiasset data', async () => {
expect(await devUtils.decodeMultiAssetData(KNOWN_MULTI_ASSET_ENCODING.assetData).callAsync()).to.deep.equal(
[
AssetProxyId.MultiAsset,
KNOWN_MULTI_ASSET_ENCODING.amounts,
KNOWN_MULTI_ASSET_ENCODING.nestedAssetData,
],
);
expect(
await devUtils.decodeMultiAssetData(KNOWN_MULTI_ASSET_ENCODING.assetData).callAsync(),
).to.deep.equal([
AssetProxyId.MultiAsset,
KNOWN_MULTI_ASSET_ENCODING.amounts,
KNOWN_MULTI_ASSET_ENCODING.nestedAssetData,
]);
});
it('should encode StaticCall data', async () => {

View File

@@ -278,15 +278,21 @@ blockchainTests.resets('matchOrders integration tests', env => {
ExchangeRevertErrors.BatchMatchOrdersErrorCodes.InvalidLengthRightSignatures,
);
let tx = deployment.exchange
.batchMatchOrders(leftOrders, rightOrders, leftOrders.map(order => order.signature), [
rightOrders[0].signature,
])
.batchMatchOrders(
leftOrders,
rightOrders,
leftOrders.map(order => order.signature),
[rightOrders[0].signature],
)
.awaitTransactionSuccessAsync({ from: matcher.address });
await expect(tx).to.revertWith(expectedError);
tx = deployment.exchange
.batchMatchOrdersWithMaximalFill(leftOrders, rightOrders, leftOrders.map(order => order.signature), [
rightOrders[0].signature,
])
.batchMatchOrdersWithMaximalFill(
leftOrders,
rightOrders,
leftOrders.map(order => order.signature),
[rightOrders[0].signature],
)
.awaitTransactionSuccessAsync({ from: matcher.address });
return expect(tx).to.revertWith(expectedError);
});
@@ -475,7 +481,10 @@ blockchainTests.resets('matchOrders integration tests', env => {
],
leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT],
matchIndices: [[0, 0], [1, 0]],
matchIndices: [
[0, 0],
[1, 0],
],
shouldMaximallyFill: false,
});
});
@@ -524,7 +533,10 @@ blockchainTests.resets('matchOrders integration tests', env => {
],
leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT],
rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
matchIndices: [[0, 0], [0, 1]],
matchIndices: [
[0, 0],
[0, 1],
],
shouldMaximallyFill: false,
});
});
@@ -626,7 +638,11 @@ blockchainTests.resets('matchOrders integration tests', env => {
],
leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
matchIndices: [[0, 0], [0, 1], [1, 1]],
matchIndices: [
[0, 0],
[0, 1],
[1, 1],
],
shouldMaximallyFill: false,
});
});
@@ -801,7 +817,11 @@ blockchainTests.resets('matchOrders integration tests', env => {
],
leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
matchIndices: [[0, 0], [1, 0], [1, 1]],
matchIndices: [
[0, 0],
[1, 0],
[1, 1],
],
shouldMaximallyFill: true,
});
});

View File

@@ -106,7 +106,12 @@ blockchainTests.fork.resets('Forwarder mainnet tests', env => {
orders[1].takerAssetAmount.dividedToIntegerBy(2),
);
const [wethSpentAmount, makerAssetAcquiredAmount] = await forwarder
.marketSellOrdersWithEth(orders, orders.map(o => o.signature), [], [])
.marketSellOrdersWithEth(
orders,
orders.map(o => o.signature),
[],
[],
)
.callAsync({
from: takerAddress,
value: ethSellAmount,
@@ -161,7 +166,13 @@ blockchainTests.fork.resets('Forwarder mainnet tests', env => {
orders[1].makerAssetAmount.dividedToIntegerBy(2),
);
const [wethSpentAmount, makerAssetAcquiredAmount] = await forwarder
.marketBuyOrdersWithEth(orders, makerAssetBuyAmount, orders.map(o => o.signature), [], [])
.marketBuyOrdersWithEth(
orders,
makerAssetBuyAmount,
orders.map(o => o.signature),
[],
[],
)
.callAsync({
from: takerAddress,
value: ethSellAmount,

View File

@@ -190,9 +190,14 @@ export function MakerMixin<TBase extends Constructor>(Base: TBase): TBase & Cons
rightTakerAssetData,
makerFeeAssetData,
takerFeeAssetData,
] = [leftMakerToken, leftTakerToken, rightMakerToken, rightTakerToken, makerFeeToken, takerFeeToken].map(
token => encodeERC20AssetData(token.address),
);
] = [
leftMakerToken,
leftTakerToken,
rightMakerToken,
rightTakerToken,
makerFeeToken,
takerFeeToken,
].map(token => encodeERC20AssetData(token.address));
// Construct and sign the left order
const leftOrder = await this.signOrderAsync({

View File

@@ -8,7 +8,10 @@ import { Actor, Constructor } from './base';
* Useful for BalanceStore.
*/
export function actorAddressesByName(actors: Actor[]): ObjectMap<string> {
return _.zipObject(actors.map(actor => actor.name), actors.map(actor => actor.address));
return _.zipObject(
actors.map(actor => actor.name),
actors.map(actor => actor.address),
);
}
/**

View File

@@ -77,19 +77,24 @@ tests('Exchange signature validation fuzz tests', env => {
before(async () => {
chainId = await env.web3Wrapper.getChainIdAsync();
accounts = await env.getAccountAddressesAsync();
privateKeys = _.zipObject(accounts, accounts.map((a, i) => constants.TESTRPC_PRIVATE_KEYS[i]));
privateKeys = _.zipObject(
accounts,
accounts.map((a, i) => constants.TESTRPC_PRIVATE_KEYS[i]),
);
deployment = await DeploymentManager.deployAsync(env, {
numErc20TokensToDeploy: 0,
numErc721TokensToDeploy: 0,
numErc1155TokensToDeploy: 0,
});
exchange = deployment.exchange;
walletContractAddress = (await TestSignatureValidationWalletContract.deployFrom0xArtifactAsync(
artifacts.TestSignatureValidationWallet,
env.provider,
env.txDefaults,
{},
)).address;
walletContractAddress = (
await TestSignatureValidationWalletContract.deployFrom0xArtifactAsync(
artifacts.TestSignatureValidationWallet,
env.provider,
env.txDefaults,
{},
)
).address;
// This just has to be a contract address that doesn't implement the
// wallet spec.
notWalletContractAddress = exchange.address;
@@ -715,7 +720,7 @@ tests('Exchange signature validation fuzz tests', env => {
invalidTestTransactionMangledSignature(),
];
const simulationEnvironment = new SimulationEnvironment(deployment, new BlockchainBalanceStore({}, {}), []);
const simulation = new class extends Simulation {
const simulation = new (class extends Simulation {
// tslint:disable-next-line: prefer-function-over-method
protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> {
while (true) {
@@ -723,7 +728,7 @@ tests('Exchange signature validation fuzz tests', env => {
yield (await action!.next()).value;
}
}
}(simulationEnvironment);
})(simulationEnvironment);
simulation.resets = true;
return simulation.fuzzAsync();
});

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "4.1.38",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "4.1.37",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "4.1.36",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "4.1.35",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "4.1.34",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "4.1.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "4.1.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "4.1.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "4.1.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "4.1.29",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.1.38 - _August 16, 2021_
* Dependencies updated
## v4.1.37 - _August 11, 2021_
* Dependencies updated
## v4.1.36 - _August 6, 2021_
* Dependencies updated
## v4.1.35 - _June 22, 2021_
* Dependencies updated
## v4.1.34 - _June 11, 2021_
* Dependencies updated
## v4.1.33 - _June 2, 2021_
* Dependencies updated
## v4.1.32 - _May 25, 2021_
* Dependencies updated
## v4.1.31 - _May 21, 2021_
* Dependencies updated
## v4.1.30 - _May 5, 2021_
* Dependencies updated
## v4.1.29 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-multisig",
"version": "4.1.29",
"version": "4.1.38",
"engines": {
"node": ">=6.12"
},
@@ -49,18 +49,18 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-asset-proxy": "^3.7.10",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/contracts-utils": "^4.7.7",
"@0x/dev-utils": "^4.2.6",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/contracts-utils": "^4.7.16",
"@0x/dev-utils": "^4.2.7",
"@0x/sol-compiler": "^4.7.3",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
"@0x/utils": "^6.4.2",
"@0x/web3-wrapper": "^7.5.2",
"@0x/utils": "^6.4.3",
"@0x/web3-wrapper": "^7.5.3",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -78,7 +78,7 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/base-contract": "^6.4.0",
"@0x/typescript-typings": "^5.2.0",
"ethereum-types": "^3.5.0"
},

View File

@@ -1,4 +1,86 @@
[
{
"timestamp": 1629079369,
"version": "2.0.45",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "2.0.44",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "2.0.43",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "2.0.42",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "2.0.41",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "2.0.40",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "2.0.39",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "2.0.38",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "2.0.37",
"changes": [
{
"note": "Patch epoch finalization issue",
"pr": 221
}
],
"timestamp": 1620214333
},
{
"timestamp": 1619596077,
"version": "2.0.36",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.0.45 - _August 16, 2021_
* Dependencies updated
## v2.0.44 - _August 11, 2021_
* Dependencies updated
## v2.0.43 - _August 6, 2021_
* Dependencies updated
## v2.0.42 - _June 22, 2021_
* Dependencies updated
## v2.0.41 - _June 11, 2021_
* Dependencies updated
## v2.0.40 - _June 2, 2021_
* Dependencies updated
## v2.0.39 - _May 25, 2021_
* Dependencies updated
## v2.0.38 - _May 21, 2021_
* Dependencies updated
## v2.0.37 - _May 5, 2021_
* Patch epoch finalization issue (#221)
## v2.0.36 - _April 28, 2021_
* Dependencies updated

View File

@@ -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.9;
pragma experimental ABIEncoderV2;
import "./interfaces/IStaking.sol";
import "./sys/MixinParams.sol";
import "./stake/MixinStake.sol";
import "./fees/MixinExchangeFees.sol";
contract StakingPatch is
IStaking,
MixinParams,
MixinStake,
MixinExchangeFees
{
/// @dev Initialize storage owned by this contract.
/// This function should not be called directly.
/// The StakingProxy contract will call it in `attachStakingContract()`.
function init()
public
onlyAuthorized
{
uint256 currentEpoch_ = currentEpoch;
uint256 prevEpoch = currentEpoch_.safeSub(1);
// Patch corrupted state
aggregatedStatsByEpoch[prevEpoch].numPoolsToFinalize = 0;
this.endEpoch();
uint256 lastPoolId_ = 57;
for (uint256 i = 1; i <= lastPoolId_; i++) {
this.finalizePool(bytes32(i));
}
// Ensure that current epoch's state is not corrupted
aggregatedStatsByEpoch[currentEpoch_].numPoolsToFinalize = 0;
}
}

View File

@@ -53,6 +53,10 @@ contract MixinExchangeFees is
{
_assertValidProtocolFee(protocolFee);
if (protocolFee == 0) {
return;
}
// Transfer the protocol fee to this address if it should be paid in
// WETH.
if (msg.value == 0) {

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-staking",
"version": "2.0.36",
"version": "2.0.45",
"engines": {
"node": ">=6.12"
},
@@ -41,7 +41,7 @@
"config": {
"publicInterfaceContracts": "IStaking,IStakingEvents,IStakingProxy,IZrxVault,LibStakingRichErrors,Staking,StakingProxy,ZrxVault,TestStaking",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
"abis": "./test/generated-artifacts/@(IStaking|IStakingEvents|IStakingProxy|IStorage|IStorageInit|IStructs|IZrxVault|LibCobbDouglas|LibFixedMath|LibFixedMathRichErrors|LibSafeDowncast|LibStakingRichErrors|MixinAbstract|MixinConstants|MixinCumulativeRewards|MixinDeploymentConstants|MixinExchangeFees|MixinExchangeManager|MixinFinalizer|MixinParams|MixinScheduler|MixinStake|MixinStakeBalances|MixinStakeStorage|MixinStakingPool|MixinStakingPoolRewards|MixinStorage|Staking|StakingProxy|TestAssertStorageParams|TestCobbDouglas|TestCumulativeRewardTracking|TestDelegatorRewards|TestExchangeManager|TestFinalizer|TestInitTarget|TestLibFixedMath|TestLibSafeDowncast|TestMixinCumulativeRewards|TestMixinParams|TestMixinScheduler|TestMixinStake|TestMixinStakeBalances|TestMixinStakeStorage|TestMixinStakingPool|TestMixinStakingPoolRewards|TestProtocolFees|TestProxyDestination|TestStaking|TestStakingNoWETH|TestStakingProxy|TestStakingProxyUnit|TestStorageLayoutAndConstants|ZrxVault).json"
"abis": "./test/generated-artifacts/@(IStaking|IStakingEvents|IStakingProxy|IStorage|IStorageInit|IStructs|IZrxVault|LibCobbDouglas|LibFixedMath|LibFixedMathRichErrors|LibSafeDowncast|LibStakingRichErrors|MixinAbstract|MixinConstants|MixinCumulativeRewards|MixinDeploymentConstants|MixinExchangeFees|MixinExchangeManager|MixinFinalizer|MixinParams|MixinScheduler|MixinStake|MixinStakeBalances|MixinStakeStorage|MixinStakingPool|MixinStakingPoolRewards|MixinStorage|Staking|StakingPatch|StakingProxy|TestAssertStorageParams|TestCobbDouglas|TestCumulativeRewardTracking|TestDelegatorRewards|TestExchangeManager|TestFinalizer|TestInitTarget|TestLibFixedMath|TestLibSafeDowncast|TestMixinCumulativeRewards|TestMixinParams|TestMixinScheduler|TestMixinStake|TestMixinStakeBalances|TestMixinStakeStorage|TestMixinStakingPool|TestMixinStakingPoolRewards|TestProtocolFees|TestProxyDestination|TestStaking|TestStakingNoWETH|TestStakingProxy|TestStakingProxyUnit|TestStorageLayoutAndConstants|ZrxVault).json"
},
"repository": {
"type": "git",
@@ -53,20 +53,20 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-asset-proxy": "^3.7.10",
"@0x/contracts-dev-utils": "^1.3.27",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-exchange-libs": "^4.3.28",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-utils": "^4.7.7",
"@0x/dev-utils": "^4.2.6",
"@0x/order-utils": "^10.4.20",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-dev-utils": "^1.3.36",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-exchange-libs": "^4.3.37",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-utils": "^4.7.16",
"@0x/dev-utils": "^4.2.7",
"@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
"@0x/web3-wrapper": "^7.5.2",
"@0x/web3-wrapper": "^7.5.3",
"@types/lodash": "4.14.104",
"@types/node": "12.12.54",
"chai": "^4.0.1",
@@ -87,10 +87,10 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/base-contract": "^6.4.0",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/utils": "^6.4.3",
"ethereum-types": "^3.5.0",
"ethereumjs-util": "^7.0.10"
},

View File

@@ -157,11 +157,11 @@ export class FinalizerActor extends BaseActor {
const delegators = delegatorsByPoolId[poolId];
delegatorBalancesByPoolId[poolId] = {};
for (const delegator of delegators) {
delegatorBalancesByPoolId[poolId][
delegator
] = (await this._stakingApiWrapper.stakingContract
.getStakeDelegatedToPoolByOwner(delegator, poolId)
.callAsync()).currentEpochBalance;
delegatorBalancesByPoolId[poolId][delegator] = (
await this._stakingApiWrapper.stakingContract
.getStakeDelegatedToPoolByOwner(delegator, poolId)
.callAsync()
).currentEpochBalance;
}
}
return delegatorBalancesByPoolId;
@@ -253,7 +253,10 @@ export class FinalizerActor extends BaseActor {
const totalFeesCollected = BigNumber.sum(...activePools.map(p => p.feesCollected));
const totalWeightedStake = BigNumber.sum(...activePools.map(p => p.weightedStake));
if (totalRewards.eq(0) || totalFeesCollected.eq(0) || totalWeightedStake.eq(0)) {
return _.zipObject(poolIds, _.times(poolIds.length, () => new BigNumber(0)));
return _.zipObject(
poolIds,
_.times(poolIds.length, () => new BigNumber(0)),
);
}
const rewards = await Promise.all(
activePools.map(async pool =>

View File

@@ -33,6 +33,7 @@ import * as MixinStakingPool from '../test/generated-artifacts/MixinStakingPool.
import * as MixinStakingPoolRewards from '../test/generated-artifacts/MixinStakingPoolRewards.json';
import * as MixinStorage from '../test/generated-artifacts/MixinStorage.json';
import * as Staking from '../test/generated-artifacts/Staking.json';
import * as StakingPatch from '../test/generated-artifacts/StakingPatch.json';
import * as StakingProxy from '../test/generated-artifacts/StakingProxy.json';
import * as TestAssertStorageParams from '../test/generated-artifacts/TestAssertStorageParams.json';
import * as TestCobbDouglas from '../test/generated-artifacts/TestCobbDouglas.json';
@@ -61,6 +62,7 @@ import * as TestStorageLayoutAndConstants from '../test/generated-artifacts/Test
import * as ZrxVault from '../test/generated-artifacts/ZrxVault.json';
export const artifacts = {
Staking: Staking as ContractArtifact,
StakingPatch: StakingPatch as ContractArtifact,
StakingProxy: StakingProxy as ContractArtifact,
ZrxVault: ZrxVault as ContractArtifact,
MixinExchangeFees: MixinExchangeFees as ContractArtifact,

View File

@@ -102,13 +102,15 @@ blockchainTests('Migration tests', env => {
});
it('should set the correct initial params', async () => {
const stakingProxyContractAddress = (await StakingProxyContract.deployFrom0xArtifactAsync(
artifacts.StakingProxy,
env.provider,
env.txDefaults,
artifacts,
stakingContract.address,
)).address;
const stakingProxyContractAddress = (
await StakingProxyContract.deployFrom0xArtifactAsync(
artifacts.StakingProxy,
env.provider,
env.txDefaults,
artifacts,
stakingContract.address,
)
).address;
const stakingProxyContract = new StakingContract(
stakingProxyContractAddress,

View File

@@ -0,0 +1,66 @@
import { blockchainTests, constants, expect, filterLogsToArguments } from '@0x/contracts-test-utils';
import { BigNumber, logUtils } from '@0x/utils';
import * as _ from 'lodash';
import { artifacts } from './artifacts';
import { StakingEvents, StakingPatchContract, StakingProxyContract, StakingProxyEvents } from './wrappers';
const abis = _.mapValues(artifacts, v => v.compilerOutput.abi);
const STAKING_PROXY = '0xa26e80e7dea86279c6d778d702cc413e6cffa777';
const STAKING_OWNER = '0x7d3455421bbc5ed534a83c88fd80387dc8271392';
const EXCHANGE_PROXY = '0xdef1c0ded9bec7f1a1670819833240f027b25eff';
blockchainTests.configure({
fork: {
unlockedAccounts: [STAKING_OWNER, EXCHANGE_PROXY],
},
});
blockchainTests.fork('Staking patch mainnet fork tests', env => {
let stakingProxyContract: StakingProxyContract;
let patchedStakingPatchContract: StakingPatchContract;
before(async () => {
stakingProxyContract = new StakingProxyContract(STAKING_PROXY, env.provider, undefined, abis);
patchedStakingPatchContract = await StakingPatchContract.deployFrom0xArtifactAsync(
artifacts.Staking,
env.provider,
env.txDefaults,
artifacts,
);
});
it('Staking proxy successfully attaches to patched logic', async () => {
const tx = await stakingProxyContract
.attachStakingContract(patchedStakingPatchContract.address)
.awaitTransactionSuccessAsync({ from: STAKING_OWNER, gasPrice: 0 }, { shouldValidate: false });
expect(filterLogsToArguments(tx.logs, StakingProxyEvents.StakingContractAttachedToProxy)).to.deep.equal([
{
newStakingPatchContractAddress: patchedStakingPatchContract.address,
},
]);
expect(filterLogsToArguments(tx.logs, StakingEvents.EpochEnded).length).to.equal(1);
expect(filterLogsToArguments(tx.logs, StakingEvents.EpochFinalized).length).to.equal(1);
logUtils.log(`${tx.gasUsed} gas used`);
});
it('Patched staking handles 0 gas protocol fees', async () => {
const staking = new StakingPatchContract(STAKING_PROXY, env.provider, undefined, abis);
const maker = '0x7b1886e49ab5433bb46f7258548092dc8cdca28b';
const zeroFeeTx = await staking
.payProtocolFee(maker, constants.NULL_ADDRESS, constants.ZERO_AMOUNT)
.awaitTransactionSuccessAsync({ from: EXCHANGE_PROXY, gasPrice: 0 }, { shouldValidate: false });
// StakingPoolEarnedRewardsInEpoch should _not_ be emitted for a zero protocol fee.
// tslint:disable-next-line:no-unused-expression
expect(filterLogsToArguments(zeroFeeTx.logs, StakingEvents.StakingPoolEarnedRewardsInEpoch)).to.be.empty;
// Coincidentally there's some ETH in the ExchangeProxy
const nonZeroFeeTx = await staking
.payProtocolFee(maker, constants.NULL_ADDRESS, new BigNumber(1))
.awaitTransactionSuccessAsync({ from: EXCHANGE_PROXY, gasPrice: 0, value: 1 }, { shouldValidate: false });
// StakingPoolEarnedRewardsInEpoch _should_ be emitted for a non-zero protocol fee.
expect(
filterLogsToArguments(nonZeroFeeTx.logs, StakingEvents.StakingPoolEarnedRewardsInEpoch),
).to.have.lengthOf(1);
});
});
// tslint:enable:no-unnecessary-type-assertion

View File

@@ -31,6 +31,7 @@ export * from '../test/generated-wrappers/mixin_staking_pool';
export * from '../test/generated-wrappers/mixin_staking_pool_rewards';
export * from '../test/generated-wrappers/mixin_storage';
export * from '../test/generated-wrappers/staking';
export * from '../test/generated-wrappers/staking_patch';
export * from '../test/generated-wrappers/staking_proxy';
export * from '../test/generated-wrappers/test_assert_storage_params';
export * from '../test/generated-wrappers/test_cobb_douglas';

View File

@@ -40,6 +40,7 @@
"test/generated-artifacts/MixinStakingPoolRewards.json",
"test/generated-artifacts/MixinStorage.json",
"test/generated-artifacts/Staking.json",
"test/generated-artifacts/StakingPatch.json",
"test/generated-artifacts/StakingProxy.json",
"test/generated-artifacts/TestAssertStorageParams.json",
"test/generated-artifacts/TestCobbDouglas.json",

View File

@@ -1,4 +1,86 @@
[
{
"timestamp": 1629079369,
"version": "5.4.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "5.4.7",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "5.4.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "5.4.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "5.4.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "5.4.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "5.4.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "5.4.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "5.4.0",
"changes": [
{
"note": "Set default ganache gas limit to 100e6",
"pr": 197
}
],
"timestamp": 1620214333
},
{
"timestamp": 1619596077,
"version": "5.3.25",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v5.4.8 - _August 16, 2021_
* Dependencies updated
## v5.4.7 - _August 11, 2021_
* Dependencies updated
## v5.4.6 - _August 6, 2021_
* Dependencies updated
## v5.4.5 - _June 22, 2021_
* Dependencies updated
## v5.4.4 - _June 11, 2021_
* Dependencies updated
## v5.4.3 - _June 2, 2021_
* Dependencies updated
## v5.4.2 - _May 25, 2021_
* Dependencies updated
## v5.4.1 - _May 21, 2021_
* Dependencies updated
## v5.4.0 - _May 5, 2021_
* Set default ganache gas limit to 100e6 (#197)
## v5.3.25 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-test-utils",
"version": "5.3.25",
"version": "5.4.8",
"engines": {
"node": ">=6.12"
},
@@ -34,7 +34,7 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils",
"devDependencies": {
"@0x/sol-compiler": "^4.7.2",
"@0x/sol-compiler": "^4.7.3",
"@0x/tslint-config": "^4.1.4",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
@@ -42,20 +42,20 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/assert": "^3.0.26",
"@0x/base-contract": "^6.3.2",
"@0x/contract-addresses": "^6.0.0",
"@0x/dev-utils": "^4.2.6",
"@0x/json-schemas": "^6.1.2",
"@0x/order-utils": "^10.4.20",
"@0x/sol-coverage": "^4.0.36",
"@0x/sol-profiler": "^4.1.26",
"@0x/sol-trace": "^3.0.36",
"@0x/subproviders": "^6.5.2",
"@0x/assert": "^3.0.27",
"@0x/base-contract": "^6.4.0",
"@0x/contract-addresses": "^6.6.0",
"@0x/dev-utils": "^4.2.7",
"@0x/json-schemas": "^6.1.3",
"@0x/order-utils": "^10.4.28",
"@0x/sol-coverage": "^4.0.37",
"@0x/sol-profiler": "^4.1.27",
"@0x/sol-trace": "^3.0.37",
"@0x/subproviders": "^6.5.3",
"@0x/types": "^3.3.3",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/web3-wrapper": "^7.5.2",
"@0x/utils": "^6.4.3",
"@0x/web3-wrapper": "^7.5.3",
"@types/bn.js": "^4.11.0",
"@types/js-combinatorics": "^0.5.29",
"@types/lodash": "4.14.104",

View File

@@ -40,6 +40,6 @@ export function verifyEventsFromLogs<TEventArgs>(
const _logs = filterLogsToArguments<TEventArgs>(logs, eventName);
expect(_logs.length, `Number of ${eventName} events emitted`).to.eq(expectedEvents.length);
_logs.forEach((log, index) => {
expect(log, `${eventName} event ${index}`).to.deep.equal(expectedEvents[index]);
expect(log, `${eventName} event ${index}`).to.deep.equal({ ...log, ...expectedEvents[index] });
});
}

View File

@@ -108,9 +108,7 @@ export async function testWithReferenceFuncAsync(
return expect.fail(
actualError,
expectedError,
`${testCaseString}: expected error message '${actualError.message}' to equal '${
expectedError.message
}'`,
`${testCaseString}: expected error message '${actualError.message}' to equal '${expectedError.message}'`,
);
}
}

View File

@@ -20,6 +20,7 @@ export let providerConfigs: Web3Config = {
shouldUseInProcessGanache: true,
shouldAllowUnlimitedContractSize: true,
hardfork: 'istanbul',
gasLimit: 100e6,
unlocked_accounts: [
'0x6cc5f688a315f3dc28a7781717a9a798a59fda7b',
'0x55dc8f21d20d4c6ed3c82916a438a413ca68e335',

View File

@@ -1,4 +1,106 @@
[
{
"timestamp": 1629079369,
"version": "1.3.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "1.3.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "1.3.0",
"changes": [
{
"note": "Added proposal 1 params and test",
"pr": 298
}
],
"timestamp": 1628225642
},
{
"timestamp": 1624356181,
"version": "1.2.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "1.2.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "1.2.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "1.2.0",
"changes": [
{
"note": "Added proposal 0 params and test",
"pr": 252
}
],
"timestamp": 1622154125
},
{
"timestamp": 1621944788,
"version": "1.1.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "1.1.7",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "1.1.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "1.1.5",
"changes": [
{
"note": "Patched votingPower logic",
"pr": 214
}
],
"timestamp": 1619825976
},
{
"timestamp": 1619596077,
"version": "1.1.4",

View File

@@ -5,6 +5,50 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v1.3.2 - _August 16, 2021_
* Dependencies updated
## v1.3.1 - _August 11, 2021_
* Dependencies updated
## v1.3.0 - _August 6, 2021_
* Added proposal 1 params and test (#298)
## v1.2.3 - _June 22, 2021_
* Dependencies updated
## v1.2.2 - _June 11, 2021_
* Dependencies updated
## v1.2.1 - _June 2, 2021_
* Dependencies updated
## v1.2.0 - _May 27, 2021_
* Added proposal 0 params and test (#252)
## v1.1.8 - _May 25, 2021_
* Dependencies updated
## v1.1.7 - _May 21, 2021_
* Dependencies updated
## v1.1.6 - _May 5, 2021_
* Dependencies updated
## v1.1.5 - _April 30, 2021_
* Patched votingPower logic (#214)
## v1.1.4 - _April 28, 2021_
* Dependencies updated

View File

@@ -21,13 +21,10 @@ pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "./IStaking.sol";
contract DefaultPoolOperator {
using LibERC20TokenV06 for IERC20TokenV06;
// Immutables
IStaking public immutable stakingProxy;
IERC20TokenV06 public immutable weth;
@@ -57,7 +54,7 @@ contract DefaultPoolOperator {
function returnStakingRewards()
external
{
uint256 wethBalance = weth.compatBalanceOf(address(this));
weth.compatTransfer(address(stakingProxy), wethBalance);
uint256 wethBalance = weth.balanceOf(address(this));
weth.transfer(address(stakingProxy), wethBalance);
}
}

View File

@@ -30,6 +30,7 @@ interface IZrxTreasury {
uint256 votingPeriod;
uint256 proposalThreshold;
uint256 quorumThreshold;
bytes32 defaultPoolId;
}
struct ProposedAction {

View File

@@ -20,8 +20,6 @@
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
@@ -32,7 +30,6 @@ import "./IZrxTreasury.sol";
contract ZrxTreasury is
IZrxTreasury
{
using LibERC20TokenV06 for IERC20TokenV06;
using LibSafeMathV06 for uint256;
using LibRichErrorsV06 for bytes;
using LibBytesV06 for bytes;
@@ -52,11 +49,9 @@ contract ZrxTreasury is
/// @dev Initializes the ZRX treasury and creates the default
/// staking pool.
/// @param stakingProxy_ The 0x staking proxy contract.
/// @param weth_ The WETH token contract.
/// @param params Immutable treasury parameters.
constructor(
IStaking stakingProxy_,
IERC20TokenV06 weth_,
TreasuryParameters memory params
)
public
@@ -66,15 +61,12 @@ contract ZrxTreasury is
"VOTING_PERIOD_TOO_LONG"
);
stakingProxy = stakingProxy_;
DefaultPoolOperator defaultPoolOperator_ = new DefaultPoolOperator(
stakingProxy_,
weth_
);
defaultPoolOperator = defaultPoolOperator_;
defaultPoolId = defaultPoolOperator_.poolId();
votingPeriod = params.votingPeriod;
proposalThreshold = params.proposalThreshold;
quorumThreshold = params.quorumThreshold;
defaultPoolId = params.defaultPoolId;
IStaking.Pool memory defaultPool = stakingProxy_.getStakingPool(params.defaultPoolId);
defaultPoolOperator = DefaultPoolOperator(defaultPool.operator);
}
// solhint-disable
@@ -286,6 +278,12 @@ contract ZrxTreasury is
// Add voting power for operated staking pools.
for (uint256 i = 0; i != operatedPoolIds.length; i++) {
for (uint256 j = 0; j != i; j++) {
require(
operatedPoolIds[i] != operatedPoolIds[j],
"getVotingPower/DUPLICATE_POOL_ID"
);
}
IStaking.Pool memory pool = stakingProxy.getStakingPool(operatedPoolIds[i]);
require(
pool.operator == account,

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-treasury",
"version": "1.1.4",
"version": "1.3.2",
"engines": {
"node": ">=6.12"
},
@@ -46,14 +46,14 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contract-addresses": "^6.0.0",
"@0x/contracts-asset-proxy": "^3.7.10",
"@0x/contracts-erc20": "^3.3.7",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-staking": "^2.0.36",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contract-addresses": "^6.6.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-erc20": "^3.3.16",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-staking": "^2.0.45",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/sol-compiler": "^4.7.3",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@types/isomorphic-fetch": "^0.0.35",
@@ -72,13 +72,13 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/protocol-utils": "^1.5.1",
"@0x/subproviders": "^6.5.2",
"@0x/base-contract": "^6.4.0",
"@0x/protocol-utils": "^1.8.2",
"@0x/subproviders": "^6.5.3",
"@0x/types": "^3.3.3",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/web3-wrapper": "^7.5.2",
"@0x/utils": "^6.4.3",
"@0x/web3-wrapper": "^7.5.3",
"ethereum-types": "^3.5.0",
"ethereumjs-util": "^7.0.10"
},

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,222 @@
import { artifacts as erc20Artifacts, ERC20TokenEvents } from '@0x/contracts-erc20';
import { StakingContract, StakingProxyContract } from '@0x/contracts-staking';
import { blockchainTests, constants, verifyEventsFromLogs } from '@0x/contracts-test-utils';
import { BigNumber, hexUtils, logUtils } from '@0x/utils';
import * as _ from 'lodash';
import { proposals } from '../src/proposals';
import { artifacts } from './artifacts';
import { ZrxTreasuryContract, ZrxTreasuryEvents } from './wrappers';
const SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/mzhu25/zeroex-staking';
const STAKING_PROXY_ADDRESS = '0xa26e80e7dea86279c6d778d702cc413e6cffa777';
const TREASURY_ADDRESS = '0x0bb1810061c2f5b2088054ee184e6c79e1591101';
const PROPOSER = process.env.PROPOSER || constants.NULL_ADDRESS;
const VOTER = '0xba4f44e774158408e2dc6c5cb65bc995f0a89180';
const VOTER_OPERATED_POOLS = ['0x0000000000000000000000000000000000000000000000000000000000000017'];
blockchainTests.configure({
fork: {
unlockedAccounts: [PROPOSER, VOTER],
},
});
async function querySubgraphAsync(operatorAddress: string): Promise<string[]> {
const query = `
{
stakingActor(id: "${operatorAddress}") {
operatedPools {
id
}
}
}
`;
const response = await fetch(SUBGRAPH_URL, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
query,
}),
});
const {
data: { stakingActor },
} = await response.json();
if (stakingActor) {
return stakingActor.operatedPools.map((pool: { id: string }) => hexUtils.leftPad(pool.id));
} else {
return [];
}
}
blockchainTests.fork.skip('Treasury proposal mainnet fork tests', env => {
let staking: StakingContract;
let stakingProxy: StakingProxyContract;
let treasury: ZrxTreasuryContract;
let votingPeriod: BigNumber;
async function fastForwardToNextEpochAsync(): Promise<void> {
const epochEndTime = await staking.getCurrentEpochEarliestEndTimeInSeconds().callAsync();
const lastBlockTime = await env.web3Wrapper.getBlockTimestampAsync('latest');
const dt = Math.max(0, epochEndTime.minus(lastBlockTime).toNumber());
await env.web3Wrapper.increaseTimeAsync(dt);
// mine next block
await env.web3Wrapper.mineBlockAsync();
const lastPoolId = new BigNumber(await staking.lastPoolId().callAsync(), 16);
const batchExecuteCalldata = [
...[...new Array(lastPoolId.toNumber())].map((_x, i) =>
staking.finalizePool(hexUtils.leftPad(i + 1)).getABIEncodedTransactionData(),
),
staking.endEpoch().getABIEncodedTransactionData(),
...[...new Array(lastPoolId.toNumber())].map((_x, i) =>
staking.finalizePool(hexUtils.leftPad(i + 1)).getABIEncodedTransactionData(),
),
...[...new Array(lastPoolId.toNumber())].map((_x, i) =>
staking.finalizePool(hexUtils.leftPad(i + 1)).getABIEncodedTransactionData(),
),
];
await stakingProxy.batchExecute(batchExecuteCalldata).awaitTransactionSuccessAsync();
}
before(async () => {
const abis = _.mapValues({ ...artifacts, ...erc20Artifacts }, v => v.compilerOutput.abi);
treasury = new ZrxTreasuryContract(TREASURY_ADDRESS, env.provider, env.txDefaults, abis);
votingPeriod = await treasury.votingPeriod().callAsync();
staking = new StakingContract(STAKING_PROXY_ADDRESS, env.provider, env.txDefaults);
stakingProxy = new StakingProxyContract(STAKING_PROXY_ADDRESS, env.provider, env.txDefaults);
});
describe('Proposal 0', () => {
it('works', async () => {
const proposal = proposals[0];
let executionEpoch: BigNumber;
if (proposal.executionEpoch) {
executionEpoch = proposal.executionEpoch;
} else {
const currentEpoch = await staking.currentEpoch().callAsync();
executionEpoch = currentEpoch.plus(2);
}
const pools = await querySubgraphAsync(PROPOSER);
const proposeTx = treasury.propose(proposal.actions, executionEpoch, proposal.description, pools);
const calldata = proposeTx.getABIEncodedTransactionData();
logUtils.log('ZrxTreasury.propose calldata:');
logUtils.log(calldata);
const proposalId = await proposeTx.callAsync({ from: PROPOSER });
const receipt = await proposeTx.awaitTransactionSuccessAsync({ from: PROPOSER });
verifyEventsFromLogs(
receipt.logs,
[
{
...proposal,
proposalId,
executionEpoch,
proposer: PROPOSER,
operatedPoolIds: pools,
},
],
ZrxTreasuryEvents.ProposalCreated,
);
await fastForwardToNextEpochAsync();
await fastForwardToNextEpochAsync();
await treasury
.castVote(proposalId, true, VOTER_OPERATED_POOLS)
.awaitTransactionSuccessAsync({ from: VOTER });
await env.web3Wrapper.increaseTimeAsync(votingPeriod.plus(1).toNumber());
await env.web3Wrapper.mineBlockAsync();
const executeTx = await treasury.execute(proposalId, proposal.actions).awaitTransactionSuccessAsync();
verifyEventsFromLogs(
executeTx.logs,
[
{
proposalId,
},
],
ZrxTreasuryEvents.ProposalExecuted,
);
const recipient = '0xf9347f751a6a1467abc722ec7d80ba2698dd9d6c';
verifyEventsFromLogs(
executeTx.logs,
[
{
_from: TREASURY_ADDRESS,
_to: recipient,
_value: new BigNumber(400_000).times('1e18'),
},
],
ERC20TokenEvents.Transfer,
);
});
});
describe('Proposal 1', () => {
it('works', async () => {
const proposal = proposals[1];
let executionEpoch: BigNumber;
if (proposal.executionEpoch) {
executionEpoch = proposal.executionEpoch;
} else {
const currentEpoch = await staking.currentEpoch().callAsync();
executionEpoch = currentEpoch.plus(2);
}
const pools = await querySubgraphAsync(PROPOSER);
const proposeTx = treasury.propose(proposal.actions, executionEpoch, proposal.description, pools);
const calldata = proposeTx.getABIEncodedTransactionData();
logUtils.log('ZrxTreasury.propose calldata:');
logUtils.log(calldata);
const proposalId = await proposeTx.callAsync({ from: PROPOSER });
const receipt = await proposeTx.awaitTransactionSuccessAsync({ from: PROPOSER });
verifyEventsFromLogs(
receipt.logs,
[
{
...proposal,
proposalId,
executionEpoch,
proposer: PROPOSER,
operatedPoolIds: pools,
},
],
ZrxTreasuryEvents.ProposalCreated,
);
await fastForwardToNextEpochAsync();
await fastForwardToNextEpochAsync();
await treasury
.castVote(proposalId, true, VOTER_OPERATED_POOLS)
.awaitTransactionSuccessAsync({ from: VOTER });
await env.web3Wrapper.increaseTimeAsync(votingPeriod.plus(1).toNumber());
await env.web3Wrapper.mineBlockAsync();
const executeTx = await treasury.execute(proposalId, proposal.actions).awaitTransactionSuccessAsync();
verifyEventsFromLogs(
executeTx.logs,
[
{
proposalId,
},
],
ZrxTreasuryEvents.ProposalExecuted,
);
const recipient = '0xab66cc8fd10457ebc9d13b9760c835f0a4cbc487';
verifyEventsFromLogs(
executeTx.logs,
[
{
_from: TREASURY_ADDRESS,
_to: recipient,
_value: new BigNumber(330_813).times('1e18'),
},
{
_from: TREASURY_ADDRESS,
_to: recipient,
_value: new BigNumber(420000).times('1e18'),
},
],
ERC20TokenEvents.Transfer,
);
});
});
});

View File

@@ -28,6 +28,7 @@ blockchainTests.resets('Treasury governance', env => {
votingPeriod: new BigNumber(3).times(stakingConstants.ONE_DAY_IN_SECONDS),
proposalThreshold: new BigNumber(100),
quorumThreshold: new BigNumber(1000),
defaultPoolId: stakingConstants.INITIAL_POOL_ID,
};
const PROPOSAL_DESCRIPTION = 'A very compelling proposal!';
const TREASURY_BALANCE = constants.INITIAL_ERC20_BALANCE;
@@ -135,6 +136,16 @@ blockchainTests.resets('Treasury governance', env => {
.approve(erc20ProxyContract.address, constants.INITIAL_ERC20_ALLOWANCE)
.awaitTransactionSuccessAsync({ from: delegator });
defaultPoolOperator = await DefaultPoolOperatorContract.deployFrom0xArtifactAsync(
artifacts.DefaultPoolOperator,
env.provider,
env.txDefaults,
{ ...artifacts, ...erc20Artifacts },
staking.address,
weth.address,
);
defaultPoolId = stakingConstants.INITIAL_POOL_ID;
const createStakingPoolTx = staking.createStakingPool(stakingConstants.PPM, false);
nonDefaultPoolId = await createStakingPoolTx.callAsync({ from: poolOperator });
await createStakingPoolTx.awaitTransactionSuccessAsync({ from: poolOperator });
@@ -145,9 +156,9 @@ blockchainTests.resets('Treasury governance', env => {
env.txDefaults,
{ ...artifacts, ...erc20Artifacts },
staking.address,
weth.address,
TREASURY_PARAMS,
);
await zrx.mint(TREASURY_BALANCE).awaitTransactionSuccessAsync();
await zrx.transfer(treasury.address, TREASURY_BALANCE).awaitTransactionSuccessAsync();
actions = [
@@ -166,10 +177,6 @@ blockchainTests.resets('Treasury governance', env => {
value: constants.ZERO_AMOUNT,
},
];
defaultPoolId = await treasury.defaultPoolId().callAsync();
const defaultPoolOperatorAddress = await treasury.defaultPoolOperator().callAsync();
defaultPoolOperator = new DefaultPoolOperatorContract(defaultPoolOperatorAddress, env.provider, env.txDefaults);
});
describe('getVotingPower()', () => {
it('Unstaked ZRX has no voting power', async () => {
@@ -222,6 +229,19 @@ blockchainTests.resets('Treasury governance', env => {
const operatorVotingPower = await treasury.getVotingPower(poolOperator, [nonDefaultPoolId]).callAsync();
expect(operatorVotingPower).to.bignumber.equal(TREASURY_PARAMS.proposalThreshold.dividedBy(2));
});
it('Reverts if given duplicate pool IDs', async () => {
await staking.stake(TREASURY_PARAMS.proposalThreshold).awaitTransactionSuccessAsync({ from: delegator });
await staking
.moveStake(
new StakeInfo(StakeStatus.Undelegated),
new StakeInfo(StakeStatus.Delegated, nonDefaultPoolId),
TREASURY_PARAMS.proposalThreshold,
)
.awaitTransactionSuccessAsync({ from: delegator });
await fastForwardToNextEpochAsync();
const tx = treasury.getVotingPower(poolOperator, [nonDefaultPoolId, nonDefaultPoolId]).callAsync();
return expect(tx).to.revertWith('getVotingPower/DUPLICATE_POOL_ID');
});
it('Correctly sums voting power delegated to multiple pools', async () => {
await staking
.stake(TREASURY_PARAMS.proposalThreshold.times(2))

View File

@@ -1,4 +1,85 @@
[
{
"timestamp": 1629079369,
"version": "4.7.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628665757,
"version": "4.7.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1628225642,
"version": "4.7.14",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1624356181,
"version": "4.7.13",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1623382456,
"version": "4.7.12",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1622609597,
"version": "4.7.11",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621944788,
"version": "4.7.10",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1621600614,
"version": "4.7.9",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1620214333,
"version": "4.7.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619596077,
"version": "4.7.7",

View File

@@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.7.16 - _August 16, 2021_
* Dependencies updated
## v4.7.15 - _August 11, 2021_
* Dependencies updated
## v4.7.14 - _August 6, 2021_
* Dependencies updated
## v4.7.13 - _June 22, 2021_
* Dependencies updated
## v4.7.12 - _June 11, 2021_
* Dependencies updated
## v4.7.11 - _June 2, 2021_
* Dependencies updated
## v4.7.10 - _May 25, 2021_
* Dependencies updated
## v4.7.9 - _May 21, 2021_
* Dependencies updated
## v4.7.8 - _May 5, 2021_
* Dependencies updated
## v4.7.7 - _April 28, 2021_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-utils",
"version": "4.7.7",
"version": "4.7.16",
"engines": {
"node": ">=6.12"
},
@@ -50,15 +50,15 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils",
"devDependencies": {
"@0x/abi-gen": "^5.5.2",
"@0x/contracts-gen": "^2.0.37",
"@0x/contracts-test-utils": "^5.3.25",
"@0x/dev-utils": "^4.2.6",
"@0x/order-utils": "^10.4.20",
"@0x/sol-compiler": "^4.7.2",
"@0x/abi-gen": "^5.6.0",
"@0x/contracts-gen": "^2.0.38",
"@0x/contracts-test-utils": "^5.4.8",
"@0x/dev-utils": "^4.2.7",
"@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.7.3",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.3",
"@0x/web3-wrapper": "^7.5.2",
"@0x/web3-wrapper": "^7.5.3",
"@types/bn.js": "^4.11.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
@@ -79,9 +79,9 @@
"typescript": "4.2.2"
},
"dependencies": {
"@0x/base-contract": "^6.3.2",
"@0x/base-contract": "^6.4.0",
"@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.2",
"@0x/utils": "^6.4.3",
"bn.js": "^4.11.8",
"ethereum-types": "^3.5.0"
},

View File

@@ -536,7 +536,11 @@ blockchainTests('LibBytes', env => {
]));
describe('copies forward within one word and one byte overlap', () =>
test([[0, 0, 1, 'one byte'], [10, 0, 11, 'eleven bytes'], [15, 0, 16, 'sixteen bytes']]));
test([
[0, 0, 1, 'one byte'],
[10, 0, 11, 'eleven bytes'],
[15, 0, 16, 'sixteen bytes'],
]));
describe('copies backward', () =>
test([
@@ -603,7 +607,11 @@ blockchainTests('LibBytes', env => {
]));
describe('copies forward within one word and one byte overlap', () =>
test([[0, 0, 1, 'one byte'], [0, 10, 11, 'eleven bytes'], [0, 15, 16, 'sixteen bytes']]));
test([
[0, 0, 1, 'one byte'],
[0, 10, 11, 'eleven bytes'],
[0, 15, 16, 'sixteen bytes'],
]));
});
describe('slice', () => {

View File

@@ -1,4 +1,128 @@
[
{
"version": "0.28.0",
"changes": [
{
"note": "Transfer output tokens in TransformERC20Feature",
"pr": 279
},
{
"note": "Add support for takerToken=0xeee... in OtcOrdersFeature",
"pr": 287
},
{
"note": "Add support for OTC orders in MultiplexFeature",
"pr": 287
},
{
"note": "Multiplex v2: Refactor into multiple files, add ETH support, and other miscellanea",
"pr": 263
}
],
"timestamp": 1629079369
},
{
"timestamp": 1628665757,
"version": "0.27.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.27.0",
"changes": [
{
"note": "Add `Clipper` as a custom liquidity source"
}
],
"timestamp": 1628225642
},
{
"version": "0.26.0",
"changes": [
{
"note": "Add Lido stETH deposit integration",
"pr": 260
}
],
"timestamp": 1624356181
},
{
"timestamp": 1623382456,
"version": "0.25.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.25.0",
"changes": [
{
"note": "Add OtcOrdersFeature",
"pr": 244
},
{
"note": "Add UniswapV3 VIP feature",
"pr": 237
}
],
"timestamp": 1622609597
},
{
"timestamp": 1621944788,
"version": "0.24.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.24.0",
"changes": [
{
"note": "Add special selectors to selector collision test",
"pr": 243
}
],
"timestamp": 1621600614
},
{
"version": "0.23.0",
"changes": [
{
"note": "Added ETH support to `MixinCurve`",
"pr": 220
},
{
"note": "Add Balancer V2 integration",
"pr": 206
}
],
"timestamp": 1620214333
},
{
"timestamp": 1619830995,
"version": "0.22.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1619825976,
"version": "0.22.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.22.1",
"changes": [
@@ -25,6 +149,10 @@
"changes": [
{
"note": "Dependencies updated"
},
{
"note": "BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap)",
"pr": 208
}
]
},

View File

@@ -5,6 +5,55 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.28.0 - _August 16, 2021_
* Transfer output tokens in TransformERC20Feature (#279)
* Add support for takerToken=0xeee... in OtcOrdersFeature (#287)
* Add support for OTC orders in MultiplexFeature (#287)
* Multiplex v2: Refactor into multiple files, add ETH support, and other miscellanea (#263)
## v0.27.1 - _August 11, 2021_
* Dependencies updated
## v0.27.0 - _August 6, 2021_
* Add `Clipper` as a custom liquidity source
## v0.26.0 - _June 22, 2021_
* Add Lido stETH deposit integration (#260)
## v0.25.1 - _June 11, 2021_
* Dependencies updated
## v0.25.0 - _June 2, 2021_
* Add OtcOrdersFeature (#244)
* Add UniswapV3 VIP feature (#237)
## v0.24.1 - _May 25, 2021_
* Dependencies updated
## v0.24.0 - _May 21, 2021_
* Add special selectors to selector collision test (#243)
## v0.23.0 - _May 5, 2021_
* Added ETH support to `MixinCurve` (#220)
* Add Balancer V2 integration (#206)
## v0.22.3 - _May 1, 2021_
* Dependencies updated
## v0.22.2 - _April 30, 2021_
* Dependencies updated
## v0.22.1 - _April 28, 2021_
* bump feature version to 1.2 (#213)
@@ -16,6 +65,7 @@ CHANGELOG
## v0.21.1 - _April 12, 2021_
* Dependencies updated
* BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap) (#208)
## v0.21.0 - _April 1, 2021_

View File

@@ -26,11 +26,13 @@ import "./features/interfaces/ITokenSpenderFeature.sol";
import "./features/interfaces/ITransformERC20Feature.sol";
import "./features/interfaces/IMetaTransactionsFeature.sol";
import "./features/interfaces/IUniswapFeature.sol";
import "./features/interfaces/IUniswapV3Feature.sol";
import "./features/interfaces/IPancakeSwapFeature.sol";
import "./features/interfaces/ILiquidityProviderFeature.sol";
import "./features/interfaces/INativeOrdersFeature.sol";
import "./features/interfaces/IBatchFillNativeOrdersFeature.sol";
import "./features/interfaces/IMultiplexFeature.sol";
import "./features/interfaces/IOtcOrdersFeature.sol";
/// @dev Interface for a fully featured Exchange Proxy.
@@ -40,11 +42,13 @@ interface IZeroEx is
ITransformERC20Feature,
IMetaTransactionsFeature,
IUniswapFeature,
IUniswapV3Feature,
IPancakeSwapFeature,
ILiquidityProviderFeature,
INativeOrdersFeature,
IBatchFillNativeOrdersFeature,
IMultiplexFeature
IMultiplexFeature,
IOtcOrdersFeature
{
// solhint-disable state-visibility

View File

@@ -48,7 +48,7 @@ contract BatchFillNativeOrdersFeature is
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "BatchFill";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 0);
constructor(address zeroExAddress)
public
@@ -170,6 +170,8 @@ contract BatchFillNativeOrdersFeature is
orders[i],
signatures[i],
takerTokenFillAmounts[i],
msg.sender,
false,
msg.sender
)
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)

View File

@@ -108,7 +108,7 @@ contract LiquidityProviderFeature is
if (!LibERC20Transformer.isTokenETH(inputToken)) {
// Transfer input ERC20 tokens to the provider.
_transferERC20Tokens(
_transferERC20TokensFrom(
inputToken,
msg.sender,
address(provider),

View File

@@ -78,7 +78,7 @@ contract MetaTransactionsFeature is
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "MetaTransactions";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 1);
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 2, 0);
/// @dev EIP712 typehash of the `MetaTransactionData` struct.
bytes32 public immutable MTX_EIP712_TYPEHASH = keccak256(
"MetaTransactionData("
@@ -251,7 +251,7 @@ contract MetaTransactionsFeature is
// Pay the fee to the sender.
if (state.mtx.feeAmount > 0) {
_transferERC20Tokens(
_transferERC20TokensFrom(
state.mtx.feeToken,
state.mtx.signer,
state.sender,
@@ -415,7 +415,9 @@ contract MetaTransactionsFeature is
outputToken: args.outputToken,
inputTokenAmount: args.inputTokenAmount,
minOutputTokenAmount: args.minOutputTokenAmount,
transformations: args.transformations
transformations: args.transformations,
useSelfBalance: false,
recipient: state.mtx.signer
})
),
state.mtx.value
@@ -498,7 +500,9 @@ contract MetaTransactionsFeature is
order,
signature,
takerTokenFillAmount,
state.mtx.signer // taker is mtx signer
state.mtx.signer, // taker is mtx signer
false,
state.mtx.signer
),
state.mtx.value
);

View File

@@ -1,803 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "../external/ILiquidityProviderSandbox.sol";
import "../fixins/FixinCommon.sol";
import "../fixins/FixinEIP712.sol";
import "../fixins/FixinTokenSpender.sol";
import "../migrations/LibMigrate.sol";
import "../transformers/LibERC20Transformer.sol";
import "../vendor/ILiquidityProvider.sol";
import "../vendor/IUniswapV2Pair.sol";
import "./interfaces/IFeature.sol";
import "./interfaces/IMultiplexFeature.sol";
import "./interfaces/INativeOrdersFeature.sol";
import "./interfaces/ITransformERC20Feature.sol";
import "./libs/LibNativeOrder.sol";
/// @dev This feature enables efficient batch and multi-hop trades
/// using different liquidity sources.
contract MultiplexFeature is
IFeature,
IMultiplexFeature,
FixinCommon,
FixinEIP712,
FixinTokenSpender
{
using LibERC20Transformer for IERC20TokenV06;
using LibSafeMathV06 for uint128;
using LibSafeMathV06 for uint256;
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "MultiplexFeature";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 1);
/// @dev The WETH token contract.
IEtherTokenV06 private immutable weth;
/// @dev The sandbox contract address.
ILiquidityProviderSandbox public immutable sandbox;
// address of the UniswapV2Factory contract.
address private constant UNISWAP_FACTORY = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
// address of the (Sushiswap) UniswapV2Factory contract.
address private constant SUSHISWAP_FACTORY = 0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac;
// Init code hash of the UniswapV2Pair contract.
uint256 private constant UNISWAP_PAIR_INIT_CODE_HASH = 0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f;
// Init code hash of the (Sushiswap) UniswapV2Pair contract.
uint256 private constant SUSHISWAP_PAIR_INIT_CODE_HASH = 0xe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303;
constructor(
address zeroExAddress,
IEtherTokenV06 weth_,
ILiquidityProviderSandbox sandbox_
)
public
FixinEIP712(zeroExAddress)
{
weth = weth_;
sandbox = sandbox_;
}
/// @dev Initialize and register this feature.
/// Should be delegatecalled by `Migrate.migrate()`.
/// @return success `LibMigrate.SUCCESS` on success.
function migrate()
external
returns (bytes4 success)
{
_registerFeatureFunction(this.batchFill.selector);
_registerFeatureFunction(this.multiHopFill.selector);
return LibMigrate.MIGRATE_SUCCESS;
}
/// @dev Executes a batch of fills selling `fillData.inputToken`
/// for `fillData.outputToken` in sequence. Refer to the
/// internal variant `_batchFill` for the allowed nested
/// operations.
/// @param fillData Encodes the input/output tokens, the sell
/// amount, and the nested operations for this batch fill.
/// @param minBuyAmount The minimum amount of `fillData.outputToken`
/// to buy. Reverts if this amount is not met.
/// @return outputTokenAmount The amount of the output token bought.
function batchFill(
BatchFillData memory fillData,
uint256 minBuyAmount
)
public
payable
override
returns (uint256 outputTokenAmount)
{
// Cache the sender's balance of the output token.
outputTokenAmount = fillData.outputToken.getTokenBalanceOf(msg.sender);
// Cache the contract's ETH balance prior to this call.
uint256 ethBalanceBefore = address(this).balance.safeSub(msg.value);
// Perform the batch fill.
_batchFill(fillData);
// The `outputTokenAmount` returned by `_batchFill` may not
// be fully accurate (e.g. due to some janky token).
outputTokenAmount = fillData.outputToken.getTokenBalanceOf(msg.sender)
.safeSub(outputTokenAmount);
require(
outputTokenAmount >= minBuyAmount,
"MultiplexFeature::batchFill/UNDERBOUGHT"
);
uint256 ethBalanceAfter = address(this).balance;
require(
ethBalanceAfter >= ethBalanceBefore,
"MultiplexFeature::batchFill/OVERSPENT_ETH"
);
// Refund ETH
if (ethBalanceAfter > ethBalanceBefore) {
_transferEth(msg.sender, ethBalanceAfter - ethBalanceBefore);
}
}
/// @dev Executes a sequence of fills "hopping" through the
/// path of tokens given by `fillData.tokens`. Refer to the
/// internal variant `_multiHopFill` for the allowed nested
/// operations.
/// @param fillData Encodes the path of tokens, the sell amount,
/// and the nested operations for this multi-hop fill.
/// @param minBuyAmount The minimum amount of the output token
/// to buy. Reverts if this amount is not met.
/// @return outputTokenAmount The amount of the output token bought.
function multiHopFill(
MultiHopFillData memory fillData,
uint256 minBuyAmount
)
public
payable
override
returns (uint256 outputTokenAmount)
{
IERC20TokenV06 outputToken = IERC20TokenV06(fillData.tokens[fillData.tokens.length - 1]);
// Cache the sender's balance of the output token.
outputTokenAmount = outputToken.getTokenBalanceOf(msg.sender);
// Cache the contract's ETH balance prior to this call.
uint256 ethBalanceBefore = address(this).balance.safeSub(msg.value);
// Perform the multi-hop fill. Pass in `msg.value` as the maximum
// allowable amount of ETH for the wrapped calls to consume.
_multiHopFill(fillData, msg.value);
// The `outputTokenAmount` returned by `_multiHopFill` may not
// be fully accurate (e.g. due to some janky token).
outputTokenAmount = outputToken.getTokenBalanceOf(msg.sender)
.safeSub(outputTokenAmount);
require(
outputTokenAmount >= minBuyAmount,
"MultiplexFeature::multiHopFill/UNDERBOUGHT"
);
uint256 ethBalanceAfter = address(this).balance;
require(
ethBalanceAfter >= ethBalanceBefore,
"MultiplexFeature::multiHopFill/OVERSPENT_ETH"
);
// Refund ETH
if (ethBalanceAfter > ethBalanceBefore) {
_transferEth(msg.sender, ethBalanceAfter - ethBalanceBefore);
}
}
// Similar to FQT. If `fillData.sellAmount` is set to `type(uint256).max`,
// this is effectively a batch fill. Otherwise it can be set to perform a
// market sell of some amount. Note that the `outputTokenAmount` returned
// by this function could theoretically be inaccurate if `msg.sender` has
// set a token allowance on an external contract that gets called during
// the execution of this function.
function _batchFill(BatchFillData memory fillData)
internal
returns (uint256 outputTokenAmount, uint256 remainingEth)
{
// Track the remaining ETH allocated to this call.
remainingEth = msg.value;
// Track the amount of input token sold.
uint256 soldAmount;
for (uint256 i = 0; i != fillData.calls.length; i++) {
// Check if we've hit our target.
if (soldAmount >= fillData.sellAmount) { break; }
WrappedBatchCall memory wrappedCall = fillData.calls[i];
// Compute the fill amount.
uint256 inputTokenAmount = LibSafeMathV06.min256(
wrappedCall.sellAmount,
fillData.sellAmount.safeSub(soldAmount)
);
if (wrappedCall.selector == INativeOrdersFeature._fillRfqOrder.selector) {
// Decode the RFQ order and signature.
(
LibNativeOrder.RfqOrder memory order,
LibSignature.Signature memory signature
) = abi.decode(
wrappedCall.data,
(LibNativeOrder.RfqOrder, LibSignature.Signature)
);
if (order.expiry <= uint64(block.timestamp)) {
bytes32 orderHash = _getEIP712Hash(
LibNativeOrder.getRfqOrderStructHash(order)
);
emit ExpiredRfqOrder(
orderHash,
order.maker,
order.expiry
);
continue;
}
require(
order.takerToken == fillData.inputToken &&
order.makerToken == fillData.outputToken,
"MultiplexFeature::_batchFill/RFQ_ORDER_INVALID_TOKENS"
);
// Try filling the RFQ order. Swallows reverts.
try
INativeOrdersFeature(address(this))._fillRfqOrder
(
order,
signature,
inputTokenAmount.safeDowncastToUint128(),
msg.sender
)
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
{
// Increment the sold and bought amounts.
soldAmount = soldAmount.safeAdd(takerTokenFilledAmount);
outputTokenAmount = outputTokenAmount.safeAdd(makerTokenFilledAmount);
} catch {}
} else if (wrappedCall.selector == this._sellToUniswap.selector) {
(address[] memory tokens, bool isSushi) = abi.decode(
wrappedCall.data,
(address[], bool)
);
require(
tokens.length >= 2 &&
tokens[0] == address(fillData.inputToken) &&
tokens[tokens.length - 1] == address(fillData.outputToken),
"MultiplexFeature::_batchFill/UNISWAP_INVALID_TOKENS"
);
// Perform the Uniswap/Sushiswap trade.
uint256 outputTokenAmount_ = _sellToUniswap(
tokens,
inputTokenAmount,
isSushi,
address(0),
msg.sender
);
// Increment the sold and bought amounts.
soldAmount = soldAmount.safeAdd(inputTokenAmount);
outputTokenAmount = outputTokenAmount.safeAdd(outputTokenAmount_);
} else if (wrappedCall.selector == this._sellToLiquidityProvider.selector) {
(address provider, bytes memory auxiliaryData) = abi.decode(
wrappedCall.data,
(address, bytes)
);
if (fillData.inputToken.isTokenETH()) {
inputTokenAmount = LibSafeMathV06.min256(
inputTokenAmount,
remainingEth
);
// Transfer the input ETH to the provider.
_transferEth(payable(provider), inputTokenAmount);
// Count that ETH as spent.
remainingEth -= inputTokenAmount;
} else {
// Transfer input ERC20 tokens to the provider.
_transferERC20Tokens(
fillData.inputToken,
msg.sender,
provider,
inputTokenAmount
);
}
// Perform the PLP trade.
uint256 outputTokenAmount_ = _sellToLiquidityProvider(
fillData.inputToken,
fillData.outputToken,
inputTokenAmount,
ILiquidityProvider(provider),
msg.sender,
auxiliaryData
);
// Increment the sold and bought amounts.
soldAmount = soldAmount.safeAdd(inputTokenAmount);
outputTokenAmount = outputTokenAmount.safeAdd(outputTokenAmount_);
} else if (wrappedCall.selector == ITransformERC20Feature._transformERC20.selector) {
ITransformERC20Feature.TransformERC20Args memory args;
args.taker = msg.sender;
args.inputToken = fillData.inputToken;
args.outputToken = fillData.outputToken;
args.inputTokenAmount = inputTokenAmount;
args.minOutputTokenAmount = 0;
uint256 ethValue;
(args.transformations, ethValue) = abi.decode(
wrappedCall.data,
(ITransformERC20Feature.Transformation[], uint256)
);
// Do not spend more than the remaining ETH.
ethValue = LibSafeMathV06.min256(
ethValue,
remainingEth
);
if (ethValue > 0) {
require(
args.inputToken.isTokenETH(),
"MultiplexFeature::_batchFill/ETH_TRANSFORM_ONLY"
);
}
try ITransformERC20Feature(address(this))._transformERC20
{value: ethValue}
(args)
returns (uint256 outputTokenAmount_)
{
remainingEth -= ethValue;
soldAmount = soldAmount.safeAdd(inputTokenAmount);
outputTokenAmount = outputTokenAmount.safeAdd(outputTokenAmount_);
} catch {}
} else if (wrappedCall.selector == this._multiHopFill.selector) {
MultiHopFillData memory multiHopFillData;
uint256 ethValue;
(
multiHopFillData.tokens,
multiHopFillData.calls,
ethValue
) = abi.decode(
wrappedCall.data,
(address[], WrappedMultiHopCall[], uint256)
);
multiHopFillData.sellAmount = inputTokenAmount;
// Do not spend more than the remaining ETH.
ethValue = LibSafeMathV06.min256(
ethValue,
remainingEth
);
// Subtract the ethValue allocated to the nested multi-hop fill.
remainingEth -= ethValue;
(uint256 outputTokenAmount_, uint256 leftoverEth) =
_multiHopFill(multiHopFillData, ethValue);
// Increment the sold and bought amounts.
soldAmount = soldAmount.safeAdd(inputTokenAmount);
outputTokenAmount = outputTokenAmount.safeAdd(outputTokenAmount_);
// Add back any ETH that wasn't used by the nested multi-hop fill.
remainingEth += leftoverEth;
} else {
revert("MultiplexFeature::_batchFill/UNRECOGNIZED_SELECTOR");
}
}
}
// Internal variant of `multiHopFill`. This function can be nested within
// a `_batchFill`.
// This function executes a sequence of fills "hopping" through the
// path of tokens given by `fillData.tokens`. The nested operations that
// can be used as "hops" are:
// - WETH.deposit (wraps ETH)
// - WETH.withdraw (unwraps WETH)
// - _sellToUniswap (executes a Uniswap/Sushiswap swap)
// - _sellToLiquidityProvider (executes a PLP swap)
// - _transformERC20 (executes arbitrary ERC20 Transformations)
// This function optimizes the number of ERC20 transfers performed
// by having each hop transfer its output tokens directly to the
// target address of the next hop. Note that the `outputTokenAmount` returned
// by this function could theoretically be inaccurate if `msg.sender` has
// set a token allowance on an external contract that gets called during
// the execution of this function.
function _multiHopFill(MultiHopFillData memory fillData, uint256 totalEth)
public
returns (uint256 outputTokenAmount, uint256 remainingEth)
{
// There should be one call/hop between every two tokens
// in the path.
// tokens[0]calls[0]>tokens[1]...calls[n-1]>tokens[n]
require(
fillData.tokens.length == fillData.calls.length + 1,
"MultiplexFeature::_multiHopFill/MISMATCHED_ARRAY_LENGTHS"
);
// Track the remaining ETH allocated to this call.
remainingEth = totalEth;
// This variable is used as the input and output amounts of
// each hop. After the final hop, this will contain the output
// amount of the multi-hop fill.
outputTokenAmount = fillData.sellAmount;
// This variable is used to cache the address to target in the
// next hop. See `_computeHopRecipient` for details.
address nextTarget;
for (uint256 i = 0; i != fillData.calls.length; i++) {
WrappedMultiHopCall memory wrappedCall = fillData.calls[i];
if (wrappedCall.selector == this._sellToUniswap.selector) {
// If the next hop supports a "transfer then execute" pattern,
// the recipient will not be `msg.sender`. See `_computeHopRecipient`
// for details.
address recipient = _computeHopRecipient(fillData.calls, i);
(address[] memory tokens, bool isSushi) = abi.decode(
wrappedCall.data,
(address[], bool)
);
// Perform the Uniswap/Sushiswap trade.
outputTokenAmount = _sellToUniswap(
tokens,
outputTokenAmount,
isSushi,
nextTarget,
recipient
);
// If the recipient was not `msg.sender`, it must be the target
// contract for the next hop.
nextTarget = recipient == msg.sender ? address(0) : recipient;
} else if (wrappedCall.selector == this._sellToLiquidityProvider.selector) {
// If the next hop supports a "transfer then execute" pattern,
// the recipient will not be `msg.sender`. See `_computeHopRecipient`
// for details.
address recipient = _computeHopRecipient(fillData.calls, i);
// If `nextTarget` was not set in the previous hop, then we
// need to send in the input ETH/tokens to the liquidity provider
// contract before executing the trade.
if (nextTarget == address(0)) {
(address provider, bytes memory auxiliaryData) = abi.decode(
wrappedCall.data,
(address, bytes)
);
// Transfer input ETH or ERC20 tokens to the liquidity
// provider contract.
if (IERC20TokenV06(fillData.tokens[i]).isTokenETH()) {
outputTokenAmount = LibSafeMathV06.min256(
outputTokenAmount,
remainingEth
);
_transferEth(payable(provider), outputTokenAmount);
remainingEth -= outputTokenAmount;
} else {
_transferERC20Tokens(
IERC20TokenV06(fillData.tokens[i]),
msg.sender,
provider,
outputTokenAmount
);
}
outputTokenAmount = _sellToLiquidityProvider(
IERC20TokenV06(fillData.tokens[i]),
IERC20TokenV06(fillData.tokens[i + 1]),
outputTokenAmount,
ILiquidityProvider(provider),
recipient,
auxiliaryData
);
} else {
(, bytes memory auxiliaryData) = abi.decode(
wrappedCall.data,
(address, bytes)
);
// Tokens and ETH have already been transferred to
// the liquidity provider contract in the previous hop.
outputTokenAmount = _sellToLiquidityProvider(
IERC20TokenV06(fillData.tokens[i]),
IERC20TokenV06(fillData.tokens[i + 1]),
outputTokenAmount,
ILiquidityProvider(nextTarget),
recipient,
auxiliaryData
);
}
// If the recipient was not `msg.sender`, it must be the target
// contract for the next hop.
nextTarget = recipient == msg.sender ? address(0) : recipient;
} else if (wrappedCall.selector == ITransformERC20Feature._transformERC20.selector) {
ITransformERC20Feature.TransformERC20Args memory args;
args.inputToken = IERC20TokenV06(fillData.tokens[i]);
args.outputToken = IERC20TokenV06(fillData.tokens[i + 1]);
args.minOutputTokenAmount = 0;
args.taker = payable(_computeHopRecipient(fillData.calls, i));
if (nextTarget != address(0)) {
// If `nextTarget` was set in the previous hop, then the input
// token was already sent to the FlashWallet. Setting
// `inputTokenAmount` to 0 indicates that no tokens need to
// be pulled into the FlashWallet before executing the
// transformations.
args.inputTokenAmount = 0;
} else if (
args.taker != msg.sender &&
!args.inputToken.isTokenETH()
) {
address flashWallet = address(
ITransformERC20Feature(address(this)).getTransformWallet()
);
// The input token has _not_ already been sent to the
// FlashWallet. We also want PayTakerTransformer to
// send the output token to some address other than
// msg.sender, so we must transfer the input token
// to the FlashWallet here.
_transferERC20Tokens(
args.inputToken,
msg.sender,
flashWallet,
outputTokenAmount
);
args.inputTokenAmount = 0;
} else {
// Otherwise, either:
// (1) args.taker == msg.sender, in which case
// `_transformERC20` will pull the input token
// into the FlashWallet, or
// (2) args.inputToken == ETH_TOKEN_ADDRESS, in which
// case ETH is attached to the call and no token
// transfer occurs.
args.inputTokenAmount = outputTokenAmount;
}
uint256 ethValue;
(args.transformations, ethValue) = abi.decode(
wrappedCall.data,
(ITransformERC20Feature.Transformation[], uint256)
);
// Do not spend more than the remaining ETH.
ethValue = LibSafeMathV06.min256(ethValue, remainingEth);
if (ethValue > 0) {
require(
args.inputToken.isTokenETH(),
"MultiplexFeature::_multiHopFill/ETH_TRANSFORM_ONLY"
);
}
// Call `_transformERC20`.
outputTokenAmount = ITransformERC20Feature(address(this))
._transformERC20{value: ethValue}(args);
// Decrement the remaining ETH.
remainingEth -= ethValue;
// If the recipient was not `msg.sender`, it must be the target
// contract for the next hop.
nextTarget = args.taker == msg.sender ? address(0) : args.taker;
} else if (wrappedCall.selector == IEtherTokenV06.deposit.selector) {
require(
i == 0,
"MultiplexFeature::_multiHopFill/DEPOSIT_FIRST_HOP_ONLY"
);
uint256 ethValue = LibSafeMathV06.min256(outputTokenAmount, remainingEth);
// Wrap ETH.
weth.deposit{value: ethValue}();
nextTarget = _computeHopRecipient(fillData.calls, i);
weth.transfer(nextTarget, ethValue);
remainingEth -= ethValue;
} else if (wrappedCall.selector == IEtherTokenV06.withdraw.selector) {
require(
i == fillData.calls.length - 1,
"MultiplexFeature::_multiHopFill/WITHDRAW_LAST_HOP_ONLY"
);
// Unwrap WETH and send to `msg.sender`.
weth.withdraw(outputTokenAmount);
_transferEth(msg.sender, outputTokenAmount);
nextTarget = address(0);
} else {
revert("MultiplexFeature::_multiHopFill/UNRECOGNIZED_SELECTOR");
}
}
}
// Similar to the UniswapFeature, but with a couple of differences:
// - Does not perform the transfer in if `pairAddress` is given,
// which indicates that the transfer in was already performed
// in the previous hop of a multi-hop fill.
// - Does not include a minBuyAmount check (which is performed in
// either `batchFill` or `multiHopFill`).
// - Takes a `recipient` address parameter, so the output of the
// final `swap` call can be sent to an address other than `msg.sender`.
function _sellToUniswap(
address[] memory tokens,
uint256 sellAmount,
bool isSushi,
address pairAddress,
address recipient
)
public
returns (uint256 outputTokenAmount)
{
require(tokens.length > 1, "MultiplexFeature::_sellToUniswap/InvalidTokensLength");
if (pairAddress == address(0)) {
pairAddress = _computeUniswapPairAddress(tokens[0], tokens[1], isSushi);
_transferERC20Tokens(
IERC20TokenV06(tokens[0]),
msg.sender,
pairAddress,
sellAmount
);
}
for (uint256 i = 0; i < tokens.length - 1; i++) {
(address inputToken, address outputToken) = (tokens[i], tokens[i + 1]);
outputTokenAmount = _computeUniswapOutputAmount(
pairAddress,
inputToken,
outputToken,
sellAmount
);
(uint256 amount0Out, uint256 amount1Out) = inputToken < outputToken
? (uint256(0), outputTokenAmount)
: (outputTokenAmount, uint256(0));
address to = i < tokens.length - 2
? _computeUniswapPairAddress(outputToken, tokens[i + 2], isSushi)
: recipient;
IUniswapV2Pair(pairAddress).swap(
amount0Out,
amount1Out,
to,
new bytes(0)
);
pairAddress = to;
sellAmount = outputTokenAmount;
}
}
// Same as the LiquidityProviderFeature, but without the transfer in
// (which is potentially done in the previous hop of a multi-hop fill)
// and without the minBuyAmount check (which is performed at the top, i.e.
// in either `batchFill` or `multiHopFill`).
function _sellToLiquidityProvider(
IERC20TokenV06 inputToken,
IERC20TokenV06 outputToken,
uint256 inputTokenAmount,
ILiquidityProvider provider,
address recipient,
bytes memory auxiliaryData
)
public
returns (uint256 outputTokenAmount)
{
uint256 balanceBefore = IERC20TokenV06(outputToken).getTokenBalanceOf(recipient);
if (IERC20TokenV06(inputToken).isTokenETH()) {
sandbox.executeSellEthForToken(
provider,
outputToken,
recipient,
0,
auxiliaryData
);
} else if (IERC20TokenV06(outputToken).isTokenETH()) {
sandbox.executeSellTokenForEth(
provider,
inputToken,
recipient,
0,
auxiliaryData
);
} else {
sandbox.executeSellTokenForToken(
provider,
inputToken,
outputToken,
recipient,
0,
auxiliaryData
);
}
outputTokenAmount = IERC20TokenV06(outputToken).getTokenBalanceOf(recipient)
.safeSub(balanceBefore);
emit LiquidityProviderSwap(
address(inputToken),
address(outputToken),
inputTokenAmount,
outputTokenAmount,
address(provider),
recipient
);
return outputTokenAmount;
}
function _transferEth(address payable recipient, uint256 amount)
private
{
(bool success,) = recipient.call{value: amount}("");
require(success, "MultiplexFeature::_transferEth/TRANSFER_FALIED");
}
// Some liquidity sources (e.g. Uniswap, Sushiswap, and PLP) can be passed
// a `recipient` parameter so the boguht tokens are transferred to the
// `recipient` address rather than `msg.sender`.
// Some liquidity sources (also Uniswap, Sushiswap, and PLP incidentally)
// support a "transfer then execute" pattern, where the token being sold
// can be transferred into the contract before calling a swap function to
// execute the trade.
// If the current hop in a multi-hop fill satisfies the first condition,
// and the next hop satisfies the second condition, the tokens bought
// in the current hop can be directly sent to the target contract of
// the next hop to save a transfer.
function _computeHopRecipient(
WrappedMultiHopCall[] memory calls,
uint256 i
)
private
view
returns (address recipient)
{
recipient = msg.sender;
if (i < calls.length - 1) {
WrappedMultiHopCall memory nextCall = calls[i + 1];
if (nextCall.selector == this._sellToUniswap.selector) {
(address[] memory tokens, bool isSushi) = abi.decode(
nextCall.data,
(address[], bool)
);
recipient = _computeUniswapPairAddress(tokens[0], tokens[1], isSushi);
} else if (nextCall.selector == this._sellToLiquidityProvider.selector) {
(recipient,) = abi.decode(
nextCall.data,
(address, bytes)
);
} else if (nextCall.selector == IEtherTokenV06.withdraw.selector) {
recipient = address(this);
} else if (nextCall.selector == ITransformERC20Feature._transformERC20.selector) {
recipient = address(
ITransformERC20Feature(address(this)).getTransformWallet()
);
}
}
require(
recipient != address(0),
"MultiplexFeature::_computeHopRecipient/RECIPIENT_IS_NULL"
);
}
// Computes the the amount of output token that would be bought
// from Uniswap/Sushiswap given the input amount.
function _computeUniswapOutputAmount(
address pairAddress,
address inputToken,
address outputToken,
uint256 inputAmount
)
private
view
returns (uint256 outputAmount)
{
require(
inputAmount > 0,
"MultiplexFeature::_computeUniswapOutputAmount/INSUFFICIENT_INPUT_AMOUNT"
);
(uint256 reserve0, uint256 reserve1,) = IUniswapV2Pair(pairAddress).getReserves();
require(
reserve0 > 0 && reserve1 > 0,
'MultiplexFeature::_computeUniswapOutputAmount/INSUFFICIENT_LIQUIDITY'
);
(uint256 inputReserve, uint256 outputReserve) = inputToken < outputToken
? (reserve0, reserve1)
: (reserve1, reserve0);
uint256 inputAmountWithFee = inputAmount.safeMul(997);
uint256 numerator = inputAmountWithFee.safeMul(outputReserve);
uint256 denominator = inputReserve.safeMul(1000).safeAdd(inputAmountWithFee);
return numerator / denominator;
}
// Computes the Uniswap/Sushiswap pair contract address for the
// given tokens.
function _computeUniswapPairAddress(
address tokenA,
address tokenB,
bool isSushi
)
private
pure
returns (address pairAddress)
{
(address token0, address token1) = tokenA < tokenB
? (tokenA, tokenB)
: (tokenB, tokenA);
if (isSushi) {
return address(uint256(keccak256(abi.encodePacked(
hex'ff',
SUSHISWAP_FACTORY,
keccak256(abi.encodePacked(token0, token1)),
SUSHISWAP_PAIR_INIT_CODE_HASH
))));
} else {
return address(uint256(keccak256(abi.encodePacked(
hex'ff',
UNISWAP_FACTORY,
keccak256(abi.encodePacked(token0, token1)),
UNISWAP_PAIR_INIT_CODE_HASH
))));
}
}
}

View File

@@ -34,7 +34,7 @@ contract NativeOrdersFeature is
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "LimitOrders";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 2, 0);
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 3, 0);
constructor(
address zeroExAddress,

View File

@@ -0,0 +1,637 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
import "../errors/LibNativeOrdersRichErrors.sol";
import "../fixins/FixinCommon.sol";
import "../fixins/FixinEIP712.sol";
import "../fixins/FixinTokenSpender.sol";
import "../migrations/LibMigrate.sol";
import "../storage/LibNativeOrdersStorage.sol";
import "../storage/LibOtcOrdersStorage.sol";
import "./interfaces/IFeature.sol";
import "./interfaces/IOtcOrdersFeature.sol";
import "./libs/LibNativeOrder.sol";
import "./libs/LibSignature.sol";
/// @dev Feature for interacting with OTC orders.
contract OtcOrdersFeature is
IFeature,
IOtcOrdersFeature,
FixinCommon,
FixinEIP712,
FixinTokenSpender
{
using LibSafeMathV06 for uint256;
using LibSafeMathV06 for uint128;
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "OtcOrders";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
/// @dev ETH pseudo-token address.
address constant private ETH_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/// @dev The WETH token contract.
IEtherTokenV06 private immutable WETH;
constructor(address zeroExAddress, IEtherTokenV06 weth)
public
FixinEIP712(zeroExAddress)
{
WETH = weth;
}
/// @dev Initialize and register this feature.
/// Should be delegatecalled by `Migrate.migrate()`.
/// @return success `LibMigrate.SUCCESS` on success.
function migrate()
external
returns (bytes4 success)
{
_registerFeatureFunction(this.fillOtcOrder.selector);
_registerFeatureFunction(this.fillOtcOrderForEth.selector);
_registerFeatureFunction(this.fillOtcOrderWithEth.selector);
_registerFeatureFunction(this.fillTakerSignedOtcOrderForEth.selector);
_registerFeatureFunction(this.fillTakerSignedOtcOrder.selector);
_registerFeatureFunction(this.batchFillTakerSignedOtcOrders.selector);
_registerFeatureFunction(this._fillOtcOrder.selector);
_registerFeatureFunction(this.getOtcOrderInfo.selector);
_registerFeatureFunction(this.getOtcOrderHash.selector);
_registerFeatureFunction(this.lastOtcTxOriginNonce.selector);
return LibMigrate.MIGRATE_SUCCESS;
}
/// @dev Fill an OTC order for up to `takerTokenFillAmount` taker tokens.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @param takerTokenFillAmount Maximum taker token amount to fill this
/// order with.
/// @return takerTokenFilledAmount How much taker token was filled.
/// @return makerTokenFilledAmount How much maker token was filled.
function fillOtcOrder(
LibNativeOrder.OtcOrder memory order,
LibSignature.Signature memory makerSignature,
uint128 takerTokenFillAmount
)
public
override
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
{
LibNativeOrder.OtcOrderInfo memory orderInfo = getOtcOrderInfo(order);
_validateOtcOrder(
order,
orderInfo,
makerSignature,
msg.sender
);
(takerTokenFilledAmount, makerTokenFilledAmount) = _settleOtcOrder(
order,
takerTokenFillAmount,
msg.sender,
msg.sender
);
emit OtcOrderFilled(
orderInfo.orderHash,
order.maker,
msg.sender,
address(order.makerToken),
address(order.takerToken),
makerTokenFilledAmount,
takerTokenFilledAmount
);
}
/// @dev Fill an OTC order for up to `takerTokenFillAmount` taker tokens.
/// Unwraps bought WETH into ETH. before sending it to
/// the taker.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @param takerTokenFillAmount Maximum taker token amount to fill this
/// order with.
/// @return takerTokenFilledAmount How much taker token was filled.
/// @return makerTokenFilledAmount How much maker token was filled.
function fillOtcOrderForEth(
LibNativeOrder.OtcOrder memory order,
LibSignature.Signature memory makerSignature,
uint128 takerTokenFillAmount
)
public
override
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
{
require(
order.makerToken == WETH,
"OtcOrdersFeature::fillOtcOrderForEth/MAKER_TOKEN_NOT_WETH"
);
LibNativeOrder.OtcOrderInfo memory orderInfo = getOtcOrderInfo(order);
_validateOtcOrder(
order,
orderInfo,
makerSignature,
msg.sender
);
(takerTokenFilledAmount, makerTokenFilledAmount) = _settleOtcOrder(
order,
takerTokenFillAmount,
msg.sender,
address(this)
);
// Unwrap WETH
WETH.withdraw(makerTokenFilledAmount);
// Transfer ETH to taker
_transferEth(msg.sender, makerTokenFilledAmount);
emit OtcOrderFilled(
orderInfo.orderHash,
order.maker,
msg.sender,
address(order.makerToken),
address(order.takerToken),
makerTokenFilledAmount,
takerTokenFilledAmount
);
}
/// @dev Fill an OTC order whose taker token is WETH for up
/// to `msg.value`.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @return takerTokenFilledAmount How much taker token was filled.
/// @return makerTokenFilledAmount How much maker token was filled.
function fillOtcOrderWithEth(
LibNativeOrder.OtcOrder memory order,
LibSignature.Signature memory makerSignature
)
public
override
payable
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
{
if (order.takerToken == WETH) {
// Wrap ETH
WETH.deposit{value: msg.value}();
} else {
require(
address(order.takerToken) == ETH_TOKEN_ADDRESS,
"OtcOrdersFeature::fillOtcOrderWithEth/INVALID_TAKER_TOKEN"
);
}
LibNativeOrder.OtcOrderInfo memory orderInfo = getOtcOrderInfo(order);
_validateOtcOrder(
order,
orderInfo,
makerSignature,
msg.sender
);
(takerTokenFilledAmount, makerTokenFilledAmount) = _settleOtcOrder(
order,
msg.value.safeDowncastToUint128(),
address(this),
msg.sender
);
if (takerTokenFilledAmount < msg.value) {
uint256 refundAmount = msg.value - uint256(takerTokenFilledAmount);
if (order.takerToken == WETH) {
WETH.withdraw(refundAmount);
}
// Refund unused ETH
_transferEth(msg.sender, refundAmount);
}
emit OtcOrderFilled(
orderInfo.orderHash,
order.maker,
msg.sender,
address(order.makerToken),
address(order.takerToken),
makerTokenFilledAmount,
takerTokenFilledAmount
);
}
/// @dev Fully fill an OTC order. "Meta-transaction" variant,
/// requires order to be signed by both maker and taker.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @param takerSignature The order signature from the taker.
function fillTakerSignedOtcOrder(
LibNativeOrder.OtcOrder memory order,
LibSignature.Signature memory makerSignature,
LibSignature.Signature memory takerSignature
)
public
override
{
LibNativeOrder.OtcOrderInfo memory orderInfo = getOtcOrderInfo(order);
address taker = LibSignature.getSignerOfHash(orderInfo.orderHash, takerSignature);
_validateOtcOrder(
order,
orderInfo,
makerSignature,
taker
);
_settleOtcOrder(
order,
order.takerAmount,
taker,
taker
);
emit OtcOrderFilled(
orderInfo.orderHash,
order.maker,
taker,
address(order.makerToken),
address(order.takerToken),
order.makerAmount,
order.takerAmount
);
}
/// @dev Fully fill an OTC order. "Meta-transaction" variant,
/// requires order to be signed by both maker and taker.
/// Unwraps bought WETH into ETH. before sending it to
/// the taker.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @param takerSignature The order signature from the taker.
function fillTakerSignedOtcOrderForEth(
LibNativeOrder.OtcOrder memory order,
LibSignature.Signature memory makerSignature,
LibSignature.Signature memory takerSignature
)
public
override
{
require(
order.makerToken == WETH,
"OtcOrdersFeature::fillTakerSignedOtcOrder/MAKER_TOKEN_NOT_WETH"
);
LibNativeOrder.OtcOrderInfo memory orderInfo = getOtcOrderInfo(order);
address taker = LibSignature.getSignerOfHash(orderInfo.orderHash, takerSignature);
_validateOtcOrder(
order,
orderInfo,
makerSignature,
taker
);
_settleOtcOrder(
order,
order.takerAmount,
taker,
address(this)
);
// Unwrap WETH
WETH.withdraw(order.makerAmount);
// Transfer ETH to taker
_transferEth(taker, order.makerAmount);
emit OtcOrderFilled(
orderInfo.orderHash,
order.maker,
taker,
address(order.makerToken),
address(order.takerToken),
order.makerAmount,
order.takerAmount
);
}
/// @dev Fills multiple taker-signed OTC orders.
/// @param orders Array of OTC orders.
/// @param makerSignatures Array of maker signatures for each order.
/// @param takerSignatures Array of taker signatures for each order.
/// @param unwrapWeth Array of booleans representing whether or not
/// to unwrap bought WETH into ETH for each order. Should be set
/// to false if the maker token is not WETH.
/// @return successes Array of booleans representing whether or not
/// each order in `orders` was filled successfully.
function batchFillTakerSignedOtcOrders(
LibNativeOrder.OtcOrder[] memory orders,
LibSignature.Signature[] memory makerSignatures,
LibSignature.Signature[] memory takerSignatures,
bool[] memory unwrapWeth
)
public
override
returns (bool[] memory successes)
{
require(
orders.length == makerSignatures.length &&
orders.length == takerSignatures.length &&
orders.length == unwrapWeth.length,
"OtcOrdersFeature::batchFillTakerSignedOtcOrders/MISMATCHED_ARRAY_LENGTHS"
);
successes = new bool[](orders.length);
for (uint256 i = 0; i != orders.length; i++) {
bytes4 fnSelector = unwrapWeth[i]
? this.fillTakerSignedOtcOrderForEth.selector
: this.fillTakerSignedOtcOrder.selector;
// Swallow reverts
(successes[i], ) = _implementation.delegatecall(
abi.encodeWithSelector(
fnSelector,
orders[i],
makerSignatures[i],
takerSignatures[i]
)
);
}
}
/// @dev Fill an OTC order for up to `takerTokenFillAmount` taker tokens.
/// Internal variant.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @param takerTokenFillAmount Maximum taker token amount to fill this
/// order with.
/// @param taker The address to fill the order in the context of.
/// @param useSelfBalance Whether to use the Exchange Proxy's balance
/// of input tokens.
/// @param recipient The recipient of the bought maker tokens.
/// @return takerTokenFilledAmount How much taker token was filled.
/// @return makerTokenFilledAmount How much maker token was filled.
function _fillOtcOrder(
LibNativeOrder.OtcOrder memory order,
LibSignature.Signature memory makerSignature,
uint128 takerTokenFillAmount,
address taker,
bool useSelfBalance,
address recipient
)
public
override
onlySelf
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
{
LibNativeOrder.OtcOrderInfo memory orderInfo = getOtcOrderInfo(order);
_validateOtcOrder(
order,
orderInfo,
makerSignature,
taker
);
(takerTokenFilledAmount, makerTokenFilledAmount) = _settleOtcOrder(
order,
takerTokenFillAmount,
useSelfBalance ? address(this) : taker,
recipient
);
emit OtcOrderFilled(
orderInfo.orderHash,
order.maker,
taker,
address(order.makerToken),
address(order.takerToken),
makerTokenFilledAmount,
takerTokenFilledAmount
);
}
/// @dev Validates an OTC order, reverting if the order cannot be
/// filled by the given taker.
/// @param order The OTC order.
/// @param orderInfo Info on the order.
/// @param makerSignature The order signature from the maker.
/// @param taker The order taker.
function _validateOtcOrder(
LibNativeOrder.OtcOrder memory order,
LibNativeOrder.OtcOrderInfo memory orderInfo,
LibSignature.Signature memory makerSignature,
address taker
)
private
view
{
// Must be fillable.
if (orderInfo.status != LibNativeOrder.OrderStatus.FILLABLE) {
LibNativeOrdersRichErrors.OrderNotFillableError(
orderInfo.orderHash,
uint8(orderInfo.status)
).rrevert();
}
// Must be a valid taker for the order.
if (order.taker != address(0) && order.taker != taker) {
LibNativeOrdersRichErrors.OrderNotFillableByTakerError(
orderInfo.orderHash,
taker,
order.taker
).rrevert();
}
LibNativeOrdersStorage.Storage storage stor =
LibNativeOrdersStorage.getStorage();
// Must be fillable by the tx.origin.
if (
order.txOrigin != tx.origin &&
!stor.originRegistry[order.txOrigin][tx.origin]
) {
LibNativeOrdersRichErrors.OrderNotFillableByOriginError(
orderInfo.orderHash,
tx.origin,
order.txOrigin
).rrevert();
}
// Maker signature must be valid for the order.
address makerSigner = LibSignature.getSignerOfHash(orderInfo.orderHash, makerSignature);
if (
makerSigner != order.maker &&
!stor.orderSignerRegistry[order.maker][makerSigner]
) {
LibNativeOrdersRichErrors.OrderNotSignedByMakerError(
orderInfo.orderHash,
makerSigner,
order.maker
).rrevert();
}
}
/// @dev Settle the trade between an OTC order's maker and taker.
/// @param order The OTC order.
/// @param takerTokenFillAmount Maximum taker token amount to fill this
/// order with.
/// @param payer The address holding the taker tokens.
/// @param recipient The recipient of the maker tokens.
/// @return takerTokenFilledAmount How much taker token was filled.
/// @return makerTokenFilledAmount How much maker token was filled.
function _settleOtcOrder(
LibNativeOrder.OtcOrder memory order,
uint128 takerTokenFillAmount,
address payer,
address recipient
)
private
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
{
{
// Unpack nonce fields
uint64 nonceBucket = uint64(order.expiryAndNonce >> 128);
uint128 nonce = uint128(order.expiryAndNonce);
// Update tx origin nonce for the order
LibOtcOrdersStorage.getStorage().txOriginNonces
[order.txOrigin][nonceBucket] = nonce;
}
if (takerTokenFillAmount == order.takerAmount) {
takerTokenFilledAmount = order.takerAmount;
makerTokenFilledAmount = order.makerAmount;
} else {
// Clamp the taker token fill amount to the fillable amount.
takerTokenFilledAmount = LibSafeMathV06.min128(
takerTokenFillAmount,
order.takerAmount
);
// Compute the maker token amount.
// This should never overflow because the values are all clamped to
// (2^128-1).
makerTokenFilledAmount = uint128(LibMathV06.getPartialAmountFloor(
uint256(takerTokenFilledAmount),
uint256(order.takerAmount),
uint256(order.makerAmount)
));
}
if (payer == address(this)) {
if (address(order.takerToken) == ETH_TOKEN_ADDRESS) {
// Transfer ETH to the maker.
payable(order.maker).transfer(takerTokenFilledAmount);
} else {
// Transfer this -> maker.
_transferERC20Tokens(
order.takerToken,
order.maker,
takerTokenFilledAmount
);
}
} else {
// Transfer taker -> maker
_transferERC20TokensFrom(
order.takerToken,
payer,
order.maker,
takerTokenFilledAmount
);
}
// Transfer maker -> recipient.
_transferERC20TokensFrom(
order.makerToken,
order.maker,
recipient,
makerTokenFilledAmount
);
}
/// @dev Get the order info for an OTC order.
/// @param order The OTC order.
/// @return orderInfo Info about the order.
function getOtcOrderInfo(LibNativeOrder.OtcOrder memory order)
public
override
view
returns (LibNativeOrder.OtcOrderInfo memory orderInfo)
{
// compute order hash.
orderInfo.orderHash = getOtcOrderHash(order);
LibOtcOrdersStorage.Storage storage stor =
LibOtcOrdersStorage.getStorage();
// Unpack expiry and nonce fields
uint64 expiry = uint64(order.expiryAndNonce >> 192);
uint64 nonceBucket = uint64(order.expiryAndNonce >> 128);
uint128 nonce = uint128(order.expiryAndNonce);
// check tx origin nonce
uint128 lastNonce = stor.txOriginNonces
[order.txOrigin]
[nonceBucket];
if (nonce <= lastNonce) {
orderInfo.status = LibNativeOrder.OrderStatus.INVALID;
return orderInfo;
}
// Check for expiration.
if (expiry <= uint64(block.timestamp)) {
orderInfo.status = LibNativeOrder.OrderStatus.EXPIRED;
return orderInfo;
}
orderInfo.status = LibNativeOrder.OrderStatus.FILLABLE;
return orderInfo;
}
/// @dev Get the canonical hash of an OTC order.
/// @param order The OTC order.
/// @return orderHash The order hash.
function getOtcOrderHash(LibNativeOrder.OtcOrder memory order)
public
override
view
returns (bytes32 orderHash)
{
return _getEIP712Hash(
LibNativeOrder.getOtcOrderStructHash(order)
);
}
/// @dev Get the last nonce used for a particular
/// tx.origin address and nonce bucket.
/// @param txOrigin The address.
/// @param nonceBucket The nonce bucket index.
/// @return lastNonce The last nonce value used.
function lastOtcTxOriginNonce(address txOrigin, uint64 nonceBucket)
public
override
view
returns (uint128 lastNonce)
{
LibOtcOrdersStorage.Storage storage stor =
LibOtcOrdersStorage.getStorage();
return stor.txOriginNonces
[txOrigin]
[nonceBucket];
}
function _transferEth(address recipient, uint256 amount)
private
{
// Transfer ETH to recipient
(bool success, bytes memory revertData) =
recipient.call{value: amount}("");
// Revert on failure
if (!success) {
revertData.rrevert();
}
}
}

View File

@@ -37,22 +37,44 @@ contract PancakeSwapFeature is
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "PancakeSwapFeature";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 1);
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 2);
/// @dev WBNB contract.
IEtherTokenV06 private immutable WBNB;
// 0xFF + address of the PancakeSwap factory contract.
uint256 constant private FF_PANCAKESWAP_FACTORY = 0xffbcfccbde45ce874adcb698cc183debcf179528120000000000000000000000;
// 0xFF + address of the PancakeSwapV2 factory contract.
uint256 constant private FF_PANCAKESWAPV2_FACTORY = 0xffca143ce32fe78f1f7019d7d551a6402fc5350c730000000000000000000000;
// 0xFF + address of the BakerySwap factory contract.
uint256 constant private FF_BAKERYSWAP_FACTORY = 0xff01bf7c66c6bd861915cdaae475042d3c4bae16a70000000000000000000000;
// 0xFF + address of the SushiSwap factory contract.
uint256 constant private FF_SUSHISWAP_FACTORY = 0xffc35DADB65012eC5796536bD9864eD8773aBc74C40000000000000000000000;
// 0xFF + address of the ApeSwap factory contract.
uint256 constant private FF_APESWAP_FACTORY = 0xff0841bd0b734e4f5853f0dd8d7ea041c241fb0da60000000000000000000000;
// 0xFF + address of the CafeSwap factory contract.
uint256 constant private FF_CAFESWAP_FACTORY = 0xff3e708fdbe3ada63fc94f8f61811196f1302137ad0000000000000000000000;
// 0xFF + address of the CheeseSwap factory contract.
uint256 constant private FF_CHEESESWAP_FACTORY = 0xffdd538e4fd1b69b7863e1f741213276a6cf1efb3b0000000000000000000000;
// 0xFF + address of the JulSwap factory contract.
uint256 constant private FF_JULSWAP_FACTORY = 0xff553990f2cba90272390f62c5bdb1681ffc8996750000000000000000000000;
// Init code hash of the PancakeSwap pair contract.
uint256 constant private PANCAKESWAP_PAIR_INIT_CODE_HASH = 0xd0d4c4cd0848c93cb4fd1f498d7013ee6bfb25783ea21593d5834f5d250ece66;
// Init code hash of the PancakeSwapV2 pair contract.
uint256 constant private PANCAKESWAPV2_PAIR_INIT_CODE_HASH = 0x00fb7f630766e6a796048ea87d01acd3068e8ff67d078148a3fa3f4a84f69bd5;
// Init code hash of the BakerySwap pair contract.
uint256 constant private BAKERYSWAP_PAIR_INIT_CODE_HASH = 0xe2e87433120e32c4738a7d8f3271f3d872cbe16241d67537139158d90bac61d3;
// Init code hash of the SushiSwap pair contract.
uint256 constant private SUSHISWAP_PAIR_INIT_CODE_HASH = 0xe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303;
// Init code hash of the ApeSwap pair contract.
uint256 constant private APESWAP_PAIR_INIT_CODE_HASH = 0xf4ccce374816856d11f00e4069e7cada164065686fbef53c6167a63ec2fd8c5b;
// Init code hash of the CafeSwap pair contract.
uint256 constant private CAFESWAP_PAIR_INIT_CODE_HASH = 0x90bcdb5d0bf0e8db3852b0b7d7e05cc8f7c6eb6d511213c5ba02d1d1dbeda8d3;
// Init code hash of the CheeseSwap pair contract.
uint256 constant private CHEESESWAP_PAIR_INIT_CODE_HASH = 0xf52c5189a89e7ca2ef4f19f2798e3900fba7a316de7cef6c5a9446621ba86286;
// Init code hash of the JulSwap pair contract.
uint256 constant private JULSWAP_PAIR_INIT_CODE_HASH = 0xb1e98e21a5335633815a8cfb3b580071c2e4561c50afd57a8746def9ed890b18;
// Mask of the lower 20 bytes of a bytes32.
uint256 constant private ADDRESS_MASK = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff;
// BNB pseudo-token address.
@@ -258,7 +280,7 @@ contract PancakeSwapFeature is
// Call pair.swap()
switch mload(0xA20) // fork
case 1 {
case 2 {
mstore(0xB00, BAKERYSWAP_PAIR_SWAP_CALL_SELECTOR_32)
}
default {
@@ -352,15 +374,40 @@ contract PancakeSwapFeature is
mstore(0xB35, PANCAKESWAP_PAIR_INIT_CODE_HASH)
}
case 1 {
mstore(0xB00, FF_PANCAKESWAPV2_FACTORY)
mstore(0xB15, salt)
mstore(0xB35, PANCAKESWAPV2_PAIR_INIT_CODE_HASH)
}
case 2 {
mstore(0xB00, FF_BAKERYSWAP_FACTORY)
mstore(0xB15, salt)
mstore(0xB35, BAKERYSWAP_PAIR_INIT_CODE_HASH)
}
default {
case 3 {
mstore(0xB00, FF_SUSHISWAP_FACTORY)
mstore(0xB15, salt)
mstore(0xB35, SUSHISWAP_PAIR_INIT_CODE_HASH)
}
case 4 {
mstore(0xB00, FF_APESWAP_FACTORY)
mstore(0xB15, salt)
mstore(0xB35, APESWAP_PAIR_INIT_CODE_HASH)
}
case 5 {
mstore(0xB00, FF_CAFESWAP_FACTORY)
mstore(0xB15, salt)
mstore(0xB35, CAFESWAP_PAIR_INIT_CODE_HASH)
}
case 6 {
mstore(0xB00, FF_CHEESESWAP_FACTORY)
mstore(0xB15, salt)
mstore(0xB35, CHEESESWAP_PAIR_INIT_CODE_HASH)
}
default {
mstore(0xB00, FF_JULSWAP_FACTORY)
mstore(0xB15, salt)
mstore(0xB35, JULSWAP_PAIR_INIT_CODE_HASH)
}
pair := and(ADDRESS_MASK, keccak256(0xB00, 0x55))
}

View File

@@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "../errors/LibTransformERC20RichErrors.sol";
@@ -51,16 +52,14 @@ contract TransformERC20Feature is
struct TransformERC20PrivateState {
IFlashWallet wallet;
address transformerDeployer;
uint256 takerOutputTokenBalanceBefore;
uint256 takerOutputTokenBalanceAfter;
uint256 recipientOutputTokenBalanceBefore;
uint256 recipientOutputTokenBalanceAfter;
}
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "TransformERC20";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 3, 1);
constructor() public {}
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 4, 0);
/// @dev Initialize and register this feature.
/// Should be delegatecalled by `Migrate.migrate()`.
@@ -76,7 +75,7 @@ contract TransformERC20Feature is
_registerFeatureFunction(this.setTransformerDeployer.selector);
_registerFeatureFunction(this.setQuoteSigner.selector);
_registerFeatureFunction(this.getQuoteSigner.selector);
_registerFeatureFunction(this.transformERC20.selector);
_registerFeatureFunction(this.transformERC20Staging.selector);
_registerFeatureFunction(this._transformERC20.selector);
if (this.getTransformWallet() == IFlashWallet(address(0))) {
// Create the transform wallet if it doesn't exist.
@@ -146,6 +145,44 @@ contract TransformERC20Feature is
LibTransformERC20Storage.getStorage().wallet = wallet;
}
/// @dev Wrapper for `transformERC20`. This selector will be temporarily
/// registered to the Exchange Proxy so that we can migrate 0x API
/// with no downtime. Once 0x API has been updated to point to this
/// function, we can safely re-register `transformERC20`, point
/// 0x API back to `transformERC20`, and deregister this function.
/// @param inputToken The token being provided by the sender.
/// If `0xeee...`, ETH is implied and should be provided with the call.`
/// @param outputToken The token to be acquired by the sender.
/// `0xeee...` implies ETH.
/// @param inputTokenAmount The amount of `inputToken` to take from the sender.
/// If set to `uint256(-1)`, the entire spendable balance of the taker
/// will be solt.
/// @param minOutputTokenAmount The minimum amount of `outputToken` the sender
/// must receive for the entire transformation to succeed. If set to zero,
/// the minimum output token transfer will not be asserted.
/// @param transformations The transformations to execute on the token balance(s)
/// in sequence.
/// @return outputTokenAmount The amount of `outputToken` received by the sender.
function transformERC20Staging(
IERC20TokenV06 inputToken,
IERC20TokenV06 outputToken,
uint256 inputTokenAmount,
uint256 minOutputTokenAmount,
Transformation[] memory transformations
)
public
payable
returns (uint256 outputTokenAmount)
{
return transformERC20(
inputToken,
outputToken,
inputTokenAmount,
minOutputTokenAmount,
transformations
);
}
/// @dev Executes a series of transformations to convert an ERC20 `inputToken`
/// to an ERC20 `outputToken`.
/// @param inputToken The token being provided by the sender.
@@ -180,7 +217,9 @@ contract TransformERC20Feature is
outputToken: outputToken,
inputTokenAmount: inputTokenAmount,
minOutputTokenAmount: minOutputTokenAmount,
transformations: transformations
transformations: transformations,
useSelfBalance: false,
recipient: msg.sender
})
);
}
@@ -208,7 +247,7 @@ contract TransformERC20Feature is
{
// If the input token amount is -1 and we are not selling ETH,
// transform the taker's entire spendable balance.
if (args.inputTokenAmount == uint256(-1)) {
if (!args.useSelfBalance && args.inputTokenAmount == uint256(-1)) {
if (LibERC20Transformer.isTokenETH(args.inputToken)) {
// We can't pull more ETH from the taker, so we just set the
// input token amount to the value attached to the call.
@@ -225,17 +264,12 @@ contract TransformERC20Feature is
state.wallet = getTransformWallet();
state.transformerDeployer = getTransformerDeployer();
// Remember the initial output token balance of the taker.
state.takerOutputTokenBalanceBefore =
LibERC20Transformer.getTokenBalanceOf(args.outputToken, args.taker);
// Remember the initial output token balance of the recipient.
state.recipientOutputTokenBalanceBefore =
LibERC20Transformer.getTokenBalanceOf(args.outputToken, args.recipient);
// Pull input tokens from the taker to the wallet and transfer attached ETH.
_transferInputTokensAndAttachedEth(
args.inputToken,
args.taker,
address(state.wallet),
args.inputTokenAmount
);
_transferInputTokensAndAttachedEth(args, address(state.wallet));
{
// Perform transformations.
@@ -244,22 +278,29 @@ contract TransformERC20Feature is
state.wallet,
args.transformations[i],
state.transformerDeployer,
args.taker
args.recipient
);
}
// Transfer output tokens from wallet to recipient
outputTokenAmount = _executeOutputTokenTransfer(
args.outputToken,
state.wallet,
args.recipient
);
}
// Compute how much output token has been transferred to the taker.
state.takerOutputTokenBalanceAfter =
LibERC20Transformer.getTokenBalanceOf(args.outputToken, args.taker);
if (state.takerOutputTokenBalanceAfter < state.takerOutputTokenBalanceBefore) {
// Compute how much output token has been transferred to the recipient.
state.recipientOutputTokenBalanceAfter =
LibERC20Transformer.getTokenBalanceOf(args.outputToken, args.recipient);
if (state.recipientOutputTokenBalanceAfter < state.recipientOutputTokenBalanceBefore) {
LibTransformERC20RichErrors.NegativeTransformERC20OutputError(
address(args.outputToken),
state.takerOutputTokenBalanceBefore - state.takerOutputTokenBalanceAfter
state.recipientOutputTokenBalanceBefore - state.recipientOutputTokenBalanceAfter
).rrevert();
}
outputTokenAmount = state.takerOutputTokenBalanceAfter.safeSub(
state.takerOutputTokenBalanceBefore
outputTokenAmount = LibSafeMathV06.min256(
outputTokenAmount,
state.recipientOutputTokenBalanceAfter.safeSub(state.recipientOutputTokenBalanceBefore)
);
// Ensure enough output token has been sent to the taker.
if (outputTokenAmount < args.minOutputTokenAmount) {
@@ -292,38 +333,49 @@ contract TransformERC20Feature is
return LibTransformERC20Storage.getStorage().wallet;
}
/// @dev Transfer input tokens from the taker and any attached ETH to `to`
/// @param inputToken The token to pull from the taker.
/// @param from The from (taker) address.
/// @dev Transfer input tokens and any attached ETH to `to`
/// @param args A `TransformERC20Args` struct.
/// @param to The recipient of tokens and ETH.
/// @param amount Amount of `inputToken` tokens to transfer.
function _transferInputTokensAndAttachedEth(
IERC20TokenV06 inputToken,
address from,
address payable to,
uint256 amount
TransformERC20Args memory args,
address payable to
)
private
{
if (
LibERC20Transformer.isTokenETH(args.inputToken) &&
msg.value < args.inputTokenAmount
) {
// Token is ETH, so the caller must attach enough ETH to the call.
LibTransformERC20RichErrors.InsufficientEthAttachedError(
msg.value,
args.inputTokenAmount
).rrevert();
}
// Transfer any attached ETH.
if (msg.value != 0) {
to.transfer(msg.value);
}
// Transfer input tokens.
if (!LibERC20Transformer.isTokenETH(inputToken) && amount != 0) {
// Token is not ETH, so pull ERC20 tokens.
_transferERC20Tokens(
inputToken,
from,
to,
amount
);
} else if (msg.value < amount) {
// Token is ETH, so the caller must attach enough ETH to the call.
LibTransformERC20RichErrors.InsufficientEthAttachedError(
msg.value,
amount
).rrevert();
if (!LibERC20Transformer.isTokenETH(args.inputToken)) {
if (args.useSelfBalance) {
// Use EP balance input token.
_transferERC20Tokens(
args.inputToken,
to,
args.inputTokenAmount
);
} else {
// Pull ERC20 tokens from taker.
_transferERC20TokensFrom(
args.inputToken,
args.taker,
to,
args.inputTokenAmount
);
}
}
}
@@ -331,12 +383,12 @@ contract TransformERC20Feature is
/// @param wallet The wallet instance.
/// @param transformation The transformation.
/// @param transformerDeployer The address of the transformer deployer.
/// @param taker The taker address.
/// @param recipient The recipient address.
function _executeTransformation(
IFlashWallet wallet,
Transformation memory transformation,
address transformerDeployer,
address payable taker
address payable recipient
)
private
{
@@ -354,7 +406,7 @@ contract TransformERC20Feature is
IERC20Transformer.transform.selector,
IERC20Transformer.TransformContext({
sender: msg.sender,
taker: taker,
recipient: recipient,
data: transformation.data
})
)
@@ -370,4 +422,52 @@ contract TransformERC20Feature is
).rrevert();
}
}
function _executeOutputTokenTransfer(
IERC20TokenV06 outputToken,
IFlashWallet wallet,
address payable recipient
)
private
returns (uint256 transferAmount)
{
transferAmount =
LibERC20Transformer.getTokenBalanceOf(outputToken, address(wallet));
if (LibERC20Transformer.isTokenETH(outputToken)) {
wallet.executeCall(
recipient,
"",
transferAmount
);
} else {
bytes memory resultData = wallet.executeCall(
payable(address(outputToken)),
abi.encodeWithSelector(
IERC20TokenV06.transfer.selector,
recipient,
transferAmount
),
0
);
if (resultData.length == 0) {
// If we get back 0 returndata, this may be a non-standard ERC-20 that
// does not return a boolean. Check that it at least contains code.
uint256 size;
assembly { size := extcodesize(outputToken) }
require(size > 0, "invalid token address, contains no code");
} else if (resultData.length >= 32) {
// If we get back at least 32 bytes, we know the target address
// contains code, and we assume it is a token that returned a boolean
// success value, which must be true.
uint256 result = LibBytesV06.readUint256(resultData, 0);
if (result != 1) {
LibRichErrorsV06.rrevert(resultData);
}
} else {
// If 0 < returndatasize < 32, the target is a contract, but not a
// valid token.
LibRichErrorsV06.rrevert(resultData);
}
}
}
}

View File

@@ -0,0 +1,447 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
import "../vendor/IUniswapV3Pool.sol";
import "../migrations/LibMigrate.sol";
import "../fixins/FixinCommon.sol";
import "../fixins/FixinTokenSpender.sol";
import "./interfaces/IFeature.sol";
import "./interfaces/IUniswapV3Feature.sol";
/// @dev VIP uniswap fill functions.
contract UniswapV3Feature is
IFeature,
IUniswapV3Feature,
FixinCommon,
FixinTokenSpender
{
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "UniswapV3Feature";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 0);
/// @dev WETH contract.
IEtherTokenV06 private immutable WETH;
/// @dev UniswapV3 Factory contract address prepended with '0xff' and left-aligned.
bytes32 private immutable UNI_FF_FACTORY_ADDRESS;
/// @dev UniswapV3 pool init code hash.
bytes32 private immutable UNI_POOL_INIT_CODE_HASH;
/// @dev Minimum size of an encoded swap path:
/// sizeof(address(inputToken) | uint24(fee) | address(outputToken))
uint256 private constant SINGLE_HOP_PATH_SIZE = 20 + 3 + 20;
/// @dev How many bytes to skip ahead in an encoded path to start at the next hop:
/// sizeof(address(inputToken) | uint24(fee))
uint256 private constant PATH_SKIP_HOP_SIZE = 20 + 3;
/// @dev The size of the swap callback data.
uint256 private constant SWAP_CALLBACK_DATA_SIZE = 128;
/// @dev Minimum tick price sqrt ratio.
uint160 internal constant MIN_PRICE_SQRT_RATIO = 4295128739;
/// @dev Minimum tick price sqrt ratio.
uint160 internal constant MAX_PRICE_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;
/// @dev Mask of lower 20 bytes.
uint256 private constant ADDRESS_MASK = 0x00ffffffffffffffffffffffffffffffffffffffff;
/// @dev Mask of lower 3 bytes.
uint256 private constant UINT24_MASK = 0xffffff;
/// @dev Construct this contract.
/// @param weth The WETH contract.
/// @param uniFactory The UniswapV3 factory contract.
/// @param poolInitCodeHash The UniswapV3 pool init code hash.
constructor(
IEtherTokenV06 weth,
address uniFactory,
bytes32 poolInitCodeHash
) public {
WETH = weth;
UNI_FF_FACTORY_ADDRESS = bytes32((uint256(0xff) << 248) | (uint256(uniFactory) << 88));
UNI_POOL_INIT_CODE_HASH = poolInitCodeHash;
}
/// @dev Initialize and register this feature.
/// Should be delegatecalled by `Migrate.migrate()`.
/// @return success `LibMigrate.SUCCESS` on success.
function migrate()
external
returns (bytes4 success)
{
_registerFeatureFunction(this.sellEthForTokenToUniswapV3.selector);
_registerFeatureFunction(this.sellTokenForEthToUniswapV3.selector);
_registerFeatureFunction(this.sellTokenForTokenToUniswapV3.selector);
_registerFeatureFunction(this._sellHeldTokenForTokenToUniswapV3.selector);
_registerFeatureFunction(this.uniswapV3SwapCallback.selector);
return LibMigrate.MIGRATE_SUCCESS;
}
/// @dev Sell attached ETH directly against uniswap v3.
/// @param encodedPath Uniswap-encoded path, where the first token is WETH.
/// @param recipient The recipient of the bought tokens. Can be zero for sender.
/// @param minBuyAmount Minimum amount of the last token in the path to buy.
/// @return buyAmount Amount of the last token in the path bought.
function sellEthForTokenToUniswapV3(
bytes memory encodedPath,
uint256 minBuyAmount,
address recipient
)
public
payable
override
returns (uint256 buyAmount)
{
// Wrap ETH.
WETH.deposit{ value: msg.value }();
return _swap(
encodedPath,
msg.value,
minBuyAmount,
address(this), // we are payer because we hold the WETH
_normalizeRecipient(recipient)
);
}
/// @dev Sell a token for ETH directly against uniswap v3.
/// @param encodedPath Uniswap-encoded path, where the last token is WETH.
/// @param sellAmount amount of the first token in the path to sell.
/// @param minBuyAmount Minimum amount of ETH to buy.
/// @param recipient The recipient of the bought tokens. Can be zero for sender.
/// @return buyAmount Amount of ETH bought.
function sellTokenForEthToUniswapV3(
bytes memory encodedPath,
uint256 sellAmount,
uint256 minBuyAmount,
address payable recipient
)
public
override
returns (uint256 buyAmount)
{
buyAmount = _swap(
encodedPath,
sellAmount,
minBuyAmount,
msg.sender,
address(this) // we are recipient because we need to unwrap WETH
);
WETH.withdraw(buyAmount);
// Transfer ETH to recipient.
(bool success, bytes memory revertData) =
_normalizeRecipient(recipient).call{ value: buyAmount }("");
if (!success) {
revertData.rrevert();
}
}
/// @dev Sell a token for another token directly against uniswap v3.
/// @param encodedPath Uniswap-encoded path.
/// @param sellAmount amount of the first token in the path to sell.
/// @param minBuyAmount Minimum amount of the last token in the path to buy.
/// @param recipient The recipient of the bought tokens. Can be zero for sender.
/// @return buyAmount Amount of the last token in the path bought.
function sellTokenForTokenToUniswapV3(
bytes memory encodedPath,
uint256 sellAmount,
uint256 minBuyAmount,
address recipient
)
public
override
returns (uint256 buyAmount)
{
buyAmount = _swap(
encodedPath,
sellAmount,
minBuyAmount,
msg.sender,
_normalizeRecipient(recipient)
);
}
/// @dev Sell a token for another token directly against uniswap v3.
/// Private variant, uses tokens held by `address(this)`.
/// @param encodedPath Uniswap-encoded path.
/// @param sellAmount amount of the first token in the path to sell.
/// @param minBuyAmount Minimum amount of the last token in the path to buy.
/// @param recipient The recipient of the bought tokens. Can be zero for sender.
/// @return buyAmount Amount of the last token in the path bought.
function _sellHeldTokenForTokenToUniswapV3(
bytes memory encodedPath,
uint256 sellAmount,
uint256 minBuyAmount,
address recipient
)
public
override
onlySelf
returns (uint256 buyAmount)
{
buyAmount = _swap(
encodedPath,
sellAmount,
minBuyAmount,
address(this),
_normalizeRecipient(recipient)
);
}
/// @dev The UniswapV3 pool swap callback which pays the funds requested
/// by the caller/pool to the pool. Can only be called by a valid
/// UniswapV3 pool.
/// @param amount0Delta Token0 amount owed.
/// @param amount1Delta Token1 amount owed.
/// @param data Arbitrary data forwarded from swap() caller. An ABI-encoded
/// struct of: inputToken, outputToken, fee, payer
function uniswapV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes calldata data
)
external
override
{
IERC20TokenV06 token0;
IERC20TokenV06 token1;
address payer;
{
uint24 fee;
// Decode the data.
require(data.length == SWAP_CALLBACK_DATA_SIZE, "UniswapFeature/INVALID_SWAP_CALLBACK_DATA");
assembly {
let p := add(36, calldataload(68))
token0 := calldataload(p)
token1 := calldataload(add(p, 32))
fee := calldataload(add(p, 64))
payer := calldataload(add(p, 96))
}
(token0, token1) = token0 < token1
? (token0, token1)
: (token1, token0);
// Only a valid pool contract can call this function.
require(
msg.sender == address(_toPool(token0, fee, token1)),
"UniswapV3Feature/INVALID_SWAP_CALLBACK_CALLER"
);
}
// Pay the amount owed to the pool.
if (amount0Delta > 0) {
_pay(token0, payer, msg.sender, uint256(amount0Delta));
} else if (amount1Delta > 0) {
_pay(token1, payer, msg.sender, uint256(amount1Delta));
} else {
revert("UniswapV3Feature/INVALID_SWAP_AMOUNTS");
}
}
// Executes successive swaps along an encoded uniswap path.
function _swap(
bytes memory encodedPath,
uint256 sellAmount,
uint256 minBuyAmount,
address payer,
address recipient
)
private
returns (uint256 buyAmount)
{
if (sellAmount != 0) {
require(sellAmount <= uint256(type(int256).max), "UniswapV3Feature/SELL_AMOUNT_OVERFLOW");
// Perform a swap for each hop in the path.
bytes memory swapCallbackData = new bytes(SWAP_CALLBACK_DATA_SIZE);
while (true) {
bool isPathMultiHop = _isPathMultiHop(encodedPath);
bool zeroForOne;
IUniswapV3Pool pool;
{
(
IERC20TokenV06 inputToken,
uint24 fee,
IERC20TokenV06 outputToken
) = _decodeFirstPoolInfoFromPath(encodedPath);
pool = _toPool(inputToken, fee, outputToken);
zeroForOne = inputToken < outputToken;
_updateSwapCallbackData(
swapCallbackData,
inputToken,
outputToken,
fee,
payer
);
}
(int256 amount0, int256 amount1) = pool.swap(
// Intermediate tokens go to this contract.
isPathMultiHop ? address(this) : recipient,
zeroForOne,
int256(sellAmount),
zeroForOne
? MIN_PRICE_SQRT_RATIO + 1
: MAX_PRICE_SQRT_RATIO - 1,
swapCallbackData
);
{
int256 _buyAmount = -(zeroForOne ? amount1 : amount0);
require(_buyAmount >= 0, "UniswapV3Feature/INVALID_BUY_AMOUNT");
buyAmount = uint256(_buyAmount);
}
if (!isPathMultiHop) {
// Done.
break;
}
// Continue with next hop.
payer = address(this); // Subsequent hops are paid for by us.
sellAmount = buyAmount;
// Skip to next hop along path.
encodedPath = _shiftHopFromPathInPlace(encodedPath);
}
}
require(minBuyAmount <= buyAmount, "UniswapV3Feature/UNDERBOUGHT");
}
// Pay tokens from `payer` to `to`, using `transferFrom()` if
// `payer` != this contract.
function _pay(
IERC20TokenV06 token,
address payer,
address to,
uint256 amount
)
private
{
if (payer != address(this)) {
_transferERC20TokensFrom(token, payer, to, amount);
} else {
_transferERC20Tokens(token, to, amount);
}
}
// Update `swapCallbackData` in place with new values.
function _updateSwapCallbackData(
bytes memory swapCallbackData,
IERC20TokenV06 inputToken,
IERC20TokenV06 outputToken,
uint24 fee,
address payer
)
private
pure
{
assembly {
let p := add(swapCallbackData, 32)
mstore(p, inputToken)
mstore(add(p, 32), outputToken)
mstore(add(p, 64), and(UINT24_MASK, fee))
mstore(add(p, 96), and(ADDRESS_MASK, payer))
}
}
// Compute the pool address given two tokens and a fee.
function _toPool(
IERC20TokenV06 inputToken,
uint24 fee,
IERC20TokenV06 outputToken
)
private
view
returns (IUniswapV3Pool pool)
{
// address(keccak256(abi.encodePacked(
// hex"ff",
// UNI_FACTORY_ADDRESS,
// keccak256(abi.encode(inputToken, outputToken, fee)),
// UNI_POOL_INIT_CODE_HASH
// )))
bytes32 ffFactoryAddress = UNI_FF_FACTORY_ADDRESS;
bytes32 poolInitCodeHash = UNI_POOL_INIT_CODE_HASH;
(IERC20TokenV06 token0, IERC20TokenV06 token1) = inputToken < outputToken
? (inputToken, outputToken)
: (outputToken, inputToken);
assembly {
let s := mload(0x40)
let p := s
mstore(p, ffFactoryAddress)
p := add(p, 21)
// Compute the inner hash in-place
mstore(p, token0)
mstore(add(p, 32), token1)
mstore(add(p, 64), and(UINT24_MASK, fee))
mstore(p, keccak256(p, 96))
p := add(p, 32)
mstore(p, poolInitCodeHash)
pool := and(ADDRESS_MASK, keccak256(s, 85))
}
}
// Return whether or not an encoded uniswap path contains more than one hop.
function _isPathMultiHop(bytes memory encodedPath)
private
pure
returns (bool isMultiHop)
{
return encodedPath.length > SINGLE_HOP_PATH_SIZE;
}
// Return the first input token, output token, and fee of an encoded uniswap path.
function _decodeFirstPoolInfoFromPath(bytes memory encodedPath)
private
pure
returns (
IERC20TokenV06 inputToken,
uint24 fee,
IERC20TokenV06 outputToken
)
{
require(encodedPath.length >= SINGLE_HOP_PATH_SIZE, "UniswapV3Feature/BAD_PATH_ENCODING");
assembly {
let p := add(encodedPath, 32)
inputToken := shr(96, mload(p))
p := add(p, 20)
fee := shr(232, mload(p))
p := add(p, 3)
outputToken := shr(96, mload(p))
}
}
// Skip past the first hop of an encoded uniswap path in-place.
function _shiftHopFromPathInPlace(bytes memory encodedPath)
private
pure
returns (bytes memory shiftedEncodedPath)
{
require(encodedPath.length >= PATH_SKIP_HOP_SIZE, "UniswapV3Feature/BAD_PATH_ENCODING");
uint256 shiftSize = PATH_SKIP_HOP_SIZE;
uint256 newSize = encodedPath.length - shiftSize;
assembly {
shiftedEncodedPath := add(encodedPath, shiftSize)
mstore(shiftedEncodedPath, newSize)
}
}
// Convert null address values to msg.sender.
function _normalizeRecipient(address recipient)
private
view
returns (address payable normalizedRecipient)
{
return recipient == address(0) ? msg.sender : payable(recipient);
}
}

View File

@@ -24,9 +24,21 @@ import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
interface IMultiplexFeature {
// Identifies the type of subcall.
enum MultiplexSubcall {
Invalid,
RFQ,
OTC,
UniswapV2,
UniswapV3,
LiquidityProvider,
TransformERC20,
BatchSell,
MultiHopSell
}
// Parameters for `batchFill`.
struct BatchFillData {
// Parameters for a batch sell.
struct BatchSellParams {
// The token being sold.
IERC20TokenV06 inputToken;
// The token being bought.
@@ -34,84 +46,182 @@ interface IMultiplexFeature {
// The amount of `inputToken` to sell.
uint256 sellAmount;
// The nested calls to perform.
WrappedBatchCall[] calls;
BatchSellSubcall[] calls;
// Whether to use the Exchange Proxy's balance
// of input tokens.
bool useSelfBalance;
// The recipient of the bought output tokens.
address recipient;
}
// Represents a call nested within a `batchFill`.
struct WrappedBatchCall {
// The selector of the function to call.
bytes4 selector;
// Amount of `inputToken` to sell.
// Represents a constituent call of a batch sell.
struct BatchSellSubcall {
// The function to call.
MultiplexSubcall id;
// Amount of input token to sell. If the highest bit is 1,
// this value represents a proportion of the total
// `sellAmount` of the batch sell. See `_normalizeSellAmount`
// for details.
uint256 sellAmount;
// ABI-encoded parameters needed to perform the call.
bytes data;
}
// Parameters for `multiHopFill`.
struct MultiHopFillData {
// Parameters for a multi-hop sell.
struct MultiHopSellParams {
// The sell path, i.e.
// tokens = [inputToken, hopToken1, ..., hopTokenN, outputToken]
address[] tokens;
// The amount of `tokens[0]` to sell.
uint256 sellAmount;
// The nested calls to perform.
WrappedMultiHopCall[] calls;
MultiHopSellSubcall[] calls;
// Whether to use the Exchange Proxy's balance
// of input tokens.
bool useSelfBalance;
// The recipient of the bought output tokens.
address recipient;
}
// Represents a call nested within a `multiHopFill`.
struct WrappedMultiHopCall {
// The selector of the function to call.
bytes4 selector;
// Represents a constituent call of a multi-hop sell.
struct MultiHopSellSubcall {
// The function to call.
MultiplexSubcall id;
// ABI-encoded parameters needed to perform the call.
bytes data;
}
event LiquidityProviderSwap(
address inputToken,
address outputToken,
uint256 inputTokenAmount,
uint256 outputTokenAmount,
address provider,
address recipient
);
struct BatchSellState {
// Tracks the amount of input token sold.
uint256 soldAmount;
// Tracks the amount of output token bought.
uint256 boughtAmount;
}
event ExpiredRfqOrder(
bytes32 orderHash,
address maker,
uint64 expiry
);
struct MultiHopSellState {
// This variable is used for the input and output amounts of
// each hop. After the final hop, this will contain the output
// amount of the multi-hop sell.
uint256 outputTokenAmount;
// For each hop in a multi-hop sell, `from` is the
// address that holds the input tokens of the hop,
// `to` is the address that receives the output tokens
// of the hop.
// See `_computeHopTarget` for details.
address from;
address to;
// The index of the current hop in the multi-hop chain.
uint256 hopIndex;
}
/// @dev Executes a batch of fills selling `fillData.inputToken`
/// for `fillData.outputToken` in sequence. Refer to the
/// internal variant `_batchFill` for the allowed nested
/// operations.
/// @param fillData Encodes the input/output tokens, the sell
/// amount, and the nested operations for this batch fill.
/// @param minBuyAmount The minimum amount of `fillData.outputToken`
/// to buy. Reverts if this amount is not met.
/// @return outputTokenAmount The amount of the output token bought.
function batchFill(
BatchFillData calldata fillData,
/// @dev Sells attached ETH for `outputToken` using the provided
/// calls.
/// @param outputToken The token to buy.
/// @param calls The calls to use to sell the attached ETH.
/// @param minBuyAmount The minimum amount of `outputToken` that
/// must be bought for this function to not revert.
/// @return boughtAmount The amount of `outputToken` bought.
function multiplexBatchSellEthForToken(
IERC20TokenV06 outputToken,
BatchSellSubcall[] calldata calls,
uint256 minBuyAmount
)
external
payable
returns (uint256 outputTokenAmount);
returns (uint256 boughtAmount);
/// @dev Executes a sequence of fills "hopping" through the
/// path of tokens given by `fillData.tokens`. Refer to the
/// internal variant `_multiHopFill` for the allowed nested
/// operations.
/// @param fillData Encodes the path of tokens, the sell amount,
/// and the nested operations for this multi-hop fill.
/// @param minBuyAmount The minimum amount of the output token
/// to buy. Reverts if this amount is not met.
/// @return outputTokenAmount The amount of the output token bought.
function multiHopFill(
MultiHopFillData calldata fillData,
/// @dev Sells `sellAmount` of the given `inputToken` for ETH
/// using the provided calls.
/// @param inputToken The token to sell.
/// @param calls The calls to use to sell the input tokens.
/// @param sellAmount The amount of `inputToken` to sell.
/// @param minBuyAmount The minimum amount of ETH that
/// must be bought for this function to not revert.
/// @return boughtAmount The amount of ETH bought.
function multiplexBatchSellTokenForEth(
IERC20TokenV06 inputToken,
BatchSellSubcall[] calldata calls,
uint256 sellAmount,
uint256 minBuyAmount
)
external
returns (uint256 boughtAmount);
/// @dev Sells `sellAmount` of the given `inputToken` for
/// `outputToken` using the provided calls.
/// @param inputToken The token to sell.
/// @param outputToken The token to buy.
/// @param calls The calls to use to sell the input tokens.
/// @param sellAmount The amount of `inputToken` to sell.
/// @param minBuyAmount The minimum amount of `outputToken`
/// that must be bought for this function to not revert.
/// @return boughtAmount The amount of `outputToken` bought.
function multiplexBatchSellTokenForToken(
IERC20TokenV06 inputToken,
IERC20TokenV06 outputToken,
BatchSellSubcall[] calldata calls,
uint256 sellAmount,
uint256 minBuyAmount
)
external
returns (uint256 boughtAmount);
/// @dev Sells attached ETH via the given sequence of tokens
/// and calls. `tokens[0]` must be WETH.
/// The last token in `tokens` is the output token that
/// will ultimately be sent to `msg.sender`
/// @param tokens The sequence of tokens to use for the sell,
/// i.e. `tokens[i]` will be sold for `tokens[i+1]` via
/// `calls[i]`.
/// @param calls The sequence of calls to use for the sell.
/// @param minBuyAmount The minimum amount of output tokens that
/// must be bought for this function to not revert.
/// @return boughtAmount The amount of output tokens bought.
function multiplexMultiHopSellEthForToken(
address[] calldata tokens,
MultiHopSellSubcall[] calldata calls,
uint256 minBuyAmount
)
external
payable
returns (uint256 outputTokenAmount);
returns (uint256 boughtAmount);
/// @dev Sells `sellAmount` of the input token (`tokens[0]`)
/// for ETH via the given sequence of tokens and calls.
/// The last token in `tokens` must be WETH.
/// @param tokens The sequence of tokens to use for the sell,
/// i.e. `tokens[i]` will be sold for `tokens[i+1]` via
/// `calls[i]`.
/// @param calls The sequence of calls to use for the sell.
/// @param minBuyAmount The minimum amount of ETH that
/// must be bought for this function to not revert.
/// @return boughtAmount The amount of ETH bought.
function multiplexMultiHopSellTokenForEth(
address[] calldata tokens,
MultiHopSellSubcall[] calldata calls,
uint256 sellAmount,
uint256 minBuyAmount
)
external
returns (uint256 boughtAmount);
/// @dev Sells `sellAmount` of the input token (`tokens[0]`)
/// via the given sequence of tokens and calls.
/// The last token in `tokens` is the output token that
/// will ultimately be sent to `msg.sender`
/// @param tokens The sequence of tokens to use for the sell,
/// i.e. `tokens[i]` will be sold for `tokens[i+1]` via
/// `calls[i]`.
/// @param calls The sequence of calls to use for the sell.
/// @param minBuyAmount The minimum amount of output tokens that
/// must be bought for this function to not revert.
/// @return boughtAmount The amount of output tokens bought.
function multiplexMultiHopSellTokenForToken(
address[] calldata tokens,
MultiHopSellSubcall[] calldata calls,
uint256 sellAmount,
uint256 minBuyAmount
)
external
returns (uint256 boughtAmount);
}

View File

@@ -126,13 +126,18 @@ interface INativeOrdersFeature is
/// @param signature The order signature.
/// @param takerTokenFillAmount Maximum taker token to fill this order with.
/// @param taker The order taker.
/// @param useSelfBalance Whether to use the ExchangeProxy's transient
/// balance of taker tokens to fill the order.
/// @param recipient The recipient of the maker tokens.
/// @return takerTokenFilledAmount How much maker token was filled.
/// @return makerTokenFilledAmount How much maker token was filled.
function _fillRfqOrder(
LibNativeOrder.RfqOrder calldata order,
LibSignature.Signature calldata signature,
uint128 takerTokenFillAmount,
address taker
address taker,
bool useSelfBalance,
address recipient
)
external
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);

View File

@@ -0,0 +1,184 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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;
pragma experimental ABIEncoderV2;
import "../libs/LibNativeOrder.sol";
import "../libs/LibSignature.sol";
/// @dev Feature for interacting with OTC orders.
interface IOtcOrdersFeature {
/// @dev Emitted whenever an `OtcOrder` is filled.
/// @param orderHash The canonical hash of the order.
/// @param maker The maker of the order.
/// @param taker The taker of the order.
/// @param makerTokenFilledAmount How much maker token was filled.
/// @param takerTokenFilledAmount How much taker token was filled.
event OtcOrderFilled(
bytes32 orderHash,
address maker,
address taker,
address makerToken,
address takerToken,
uint128 makerTokenFilledAmount,
uint128 takerTokenFilledAmount
);
/// @dev Fill an OTC order for up to `takerTokenFillAmount` taker tokens.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @param takerTokenFillAmount Maximum taker token amount to fill this
/// order with.
/// @return takerTokenFilledAmount How much taker token was filled.
/// @return makerTokenFilledAmount How much maker token was filled.
function fillOtcOrder(
LibNativeOrder.OtcOrder calldata order,
LibSignature.Signature calldata makerSignature,
uint128 takerTokenFillAmount
)
external
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
/// @dev Fill an OTC order for up to `takerTokenFillAmount` taker tokens.
/// Unwraps bought WETH into ETH before sending it to
/// the taker.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @param takerTokenFillAmount Maximum taker token amount to fill this
/// order with.
/// @return takerTokenFilledAmount How much taker token was filled.
/// @return makerTokenFilledAmount How much maker token was filled.
function fillOtcOrderForEth(
LibNativeOrder.OtcOrder calldata order,
LibSignature.Signature calldata makerSignature,
uint128 takerTokenFillAmount
)
external
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
/// @dev Fill an OTC order whose taker token is WETH for up
/// to `msg.value`.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @return takerTokenFilledAmount How much taker token was filled.
/// @return makerTokenFilledAmount How much maker token was filled.
function fillOtcOrderWithEth(
LibNativeOrder.OtcOrder calldata order,
LibSignature.Signature calldata makerSignature
)
external
payable
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
/// @dev Fully fill an OTC order. "Meta-transaction" variant,
/// requires order to be signed by both maker and taker.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @param takerSignature The order signature from the taker.
function fillTakerSignedOtcOrder(
LibNativeOrder.OtcOrder calldata order,
LibSignature.Signature calldata makerSignature,
LibSignature.Signature calldata takerSignature
)
external;
/// @dev Fully fill an OTC order. "Meta-transaction" variant,
/// requires order to be signed by both maker and taker.
/// Unwraps bought WETH into ETH before sending it to
/// the taker.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @param takerSignature The order signature from the taker.
function fillTakerSignedOtcOrderForEth(
LibNativeOrder.OtcOrder calldata order,
LibSignature.Signature calldata makerSignature,
LibSignature.Signature calldata takerSignature
)
external;
/// @dev Fills multiple taker-signed OTC orders.
/// @param orders Array of OTC orders.
/// @param makerSignatures Array of maker signatures for each order.
/// @param takerSignatures Array of taker signatures for each order.
/// @param unwrapWeth Array of booleans representing whether or not
/// to unwrap bought WETH into ETH for each order. Should be set
/// to false if the maker token is not WETH.
/// @return successes Array of booleans representing whether or not
/// each order in `orders` was filled successfully.
function batchFillTakerSignedOtcOrders(
LibNativeOrder.OtcOrder[] calldata orders,
LibSignature.Signature[] calldata makerSignatures,
LibSignature.Signature[] calldata takerSignatures,
bool[] calldata unwrapWeth
)
external
returns (bool[] memory successes);
/// @dev Fill an OTC order for up to `takerTokenFillAmount` taker tokens.
/// Internal variant.
/// @param order The OTC order.
/// @param makerSignature The order signature from the maker.
/// @param takerTokenFillAmount Maximum taker token amount to fill this
/// order with.
/// @param taker The address to fill the order in the context of.
/// @param useSelfBalance Whether to use the Exchange Proxy's balance
/// of input tokens.
/// @param recipient The recipient of the bought maker tokens.
/// @return takerTokenFilledAmount How much taker token was filled.
/// @return makerTokenFilledAmount How much maker token was filled.
function _fillOtcOrder(
LibNativeOrder.OtcOrder calldata order,
LibSignature.Signature calldata makerSignature,
uint128 takerTokenFillAmount,
address taker,
bool useSelfBalance,
address recipient
)
external
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
/// @dev Get the order info for an OTC order.
/// @param order The OTC order.
/// @return orderInfo Info about the order.
function getOtcOrderInfo(LibNativeOrder.OtcOrder calldata order)
external
view
returns (LibNativeOrder.OtcOrderInfo memory orderInfo);
/// @dev Get the canonical hash of an OTC order.
/// @param order The OTC order.
/// @return orderHash The order hash.
function getOtcOrderHash(LibNativeOrder.OtcOrder calldata order)
external
view
returns (bytes32 orderHash);
/// @dev Get the last nonce used for a particular
/// tx.origin address and nonce bucket.
/// @param txOrigin The address.
/// @param nonceBucket The nonce bucket index.
/// @return lastNonce The last nonce value used.
function lastOtcTxOriginNonce(address txOrigin, uint64 nonceBucket)
external
view
returns (uint128 lastNonce);
}

View File

@@ -23,16 +23,21 @@ pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
/// @dev VIP PancakeSwap/BakerySwap/SushiSwap fill functions.
/// @dev VIP PancakeSwap (and forks) fill functions.
interface IPancakeSwapFeature {
enum ProtocolFork {
PancakeSwap,
PancakeSwapV2,
BakerySwap,
SushiSwap
SushiSwap,
ApeSwap,
CafeSwap,
CheeseSwap,
JulSwap
}
/// @dev Efficiently sell directly to PancakeSwap/BakerySwap/Sushiswap.
/// @dev Efficiently sell directly to PancakeSwap (and forks).
/// @param tokens Sell path.
/// @param sellAmount of `tokens[0]` Amount to sell.
/// @param minBuyAmount Minimum amount of `tokens[-1]` to buy.

Some files were not shown because too many files have changed in this diff Show More