Compare commits
	
		
			96 Commits
		
	
	
		
			@0x/contra
			...
			protocol@f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					fb249f02fc | ||
| 
						 | 
					fdf04ef275 | ||
| 
						 | 
					b0f5f634f2 | ||
| 
						 | 
					6ee0108565 | ||
| 
						 | 
					c73097e688 | ||
| 
						 | 
					a2d42b07b5 | ||
| 
						 | 
					f9a794af93 | ||
| 
						 | 
					a2643674ca | ||
| 
						 | 
					c00ce9daac | ||
| 
						 | 
					c68b5d7844 | ||
| 
						 | 
					09ed106d4c | ||
| 
						 | 
					a6b92fc658 | ||
| 
						 | 
					4be4a1a30b | ||
| 
						 | 
					9bede5d331 | ||
| 
						 | 
					b50d4aee6d | ||
| 
						 | 
					55bc367bd6 | ||
| 
						 | 
					7a59b7eafe | ||
| 
						 | 
					9e59d41e44 | ||
| 
						 | 
					475e6c7bca | ||
| 
						 | 
					dbc5a5293e | ||
| 
						 | 
					f4bd2bd0d8 | ||
| 
						 | 
					f1782a83ba | ||
| 
						 | 
					cbade0d558 | ||
| 
						 | 
					fe0c26387c | ||
| 
						 | 
					c03a014740 | ||
| 
						 | 
					84e6d788aa | ||
| 
						 | 
					cd296b8767 | ||
| 
						 | 
					5946d32a7d | ||
| 
						 | 
					842dd8572b | ||
| 
						 | 
					33e260f9db | ||
| 
						 | 
					c44f8d0060 | ||
| 
						 | 
					411548a33e | ||
| 
						 | 
					9a17ce1383 | ||
| 
						 | 
					2b120d0669 | ||
| 
						 | 
					6d877d5242 | ||
| 
						 | 
					e4abd690e7 | ||
| 
						 | 
					2a194384b6 | ||
| 
						 | 
					1e069e6f8a | ||
| 
						 | 
					a019bb913d | ||
| 
						 | 
					9ce73931f7 | ||
| 
						 | 
					97020df178 | ||
| 
						 | 
					dfb7b3de8f | ||
| 
						 | 
					9e152912fe | ||
| 
						 | 
					b2c2f1e1aa | ||
| 
						 | 
					629c7d8e92 | ||
| 
						 | 
					62f24d4356 | ||
| 
						 | 
					ae281c33ca | ||
| 
						 | 
					5d034dd106 | ||
| 
						 | 
					c1f8df0eca | ||
| 
						 | 
					76dda9eeda | ||
| 
						 | 
					a9b84a92ac | ||
| 
						 | 
					0f7e881899 | ||
| 
						 | 
					6045f777ab | ||
| 
						 | 
					5a15044ead | ||
| 
						 | 
					a69d76e487 | ||
| 
						 | 
					3adfcdffa8 | ||
| 
						 | 
					164a5d44d9 | ||
| 
						 | 
					70ddab0231 | ||
| 
						 | 
					7bf009fbf6 | ||
| 
						 | 
					525bc8197b | ||
| 
						 | 
					24397c51a8 | ||
| 
						 | 
					06b3464756 | ||
| 
						 | 
					bbaa90bd9a | ||
| 
						 | 
					5c683cbc0f | ||
| 
						 | 
					95345f18bc | ||
| 
						 | 
					4c3fbe83ac | ||
| 
						 | 
					7caa43d02c | ||
| 
						 | 
					3d4c03c9df | ||
| 
						 | 
					22e1ed35d3 | ||
| 
						 | 
					dabe6fd793 | ||
| 
						 | 
					3cc639c8d0 | ||
| 
						 | 
					22c8e0b6db | ||
| 
						 | 
					f3ca4293bc | ||
| 
						 | 
					db3e076d03 | ||
| 
						 | 
					1a6759820a | ||
| 
						 | 
					61c5e7b948 | ||
| 
						 | 
					5fd78ef32f | ||
| 
						 | 
					14ff9b827c | ||
| 
						 | 
					598dc2cd71 | ||
| 
						 | 
					08e1c5109f | ||
| 
						 | 
					6f7a843742 | ||
| 
						 | 
					c9c9615bb5 | ||
| 
						 | 
					f98609686d | ||
| 
						 | 
					5b8bbc34e8 | ||
| 
						 | 
					49cb00a9ab | ||
| 
						 | 
					74b240fb88 | ||
| 
						 | 
					514f9d2621 | ||
| 
						 | 
					fa78d1092a | ||
| 
						 | 
					297342092b | ||
| 
						 | 
					076f263a86 | ||
| 
						 | 
					0c56207abc | ||
| 
						 | 
					23953d8a5a | ||
| 
						 | 
					c6919eb25a | ||
| 
						 | 
					d509604b52 | ||
| 
						 | 
					a74a3450eb | ||
| 
						 | 
					72c5399b9d | 
@@ -1,25 +1,25 @@
 | 
				
			|||||||
version: 2
 | 
					version: 2.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
    build:
 | 
					    build:
 | 
				
			||||||
        resource_class: medium+
 | 
					        resource_class: large
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
        environment:
 | 
					        environment:
 | 
				
			||||||
            CONTRACTS_COMMIT_HASH: '9ed05f5'
 | 
					            NODE_OPTIONS: '--max-old-space-size=6442'
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
            - checkout
 | 
					            - checkout
 | 
				
			||||||
            - run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
 | 
					            - run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
 | 
				
			||||||
            - run:
 | 
					            - run:
 | 
				
			||||||
                  name: install-yarn
 | 
					                  name: install-yarn
 | 
				
			||||||
                  command: npm install --force --global yarn@1.17.0
 | 
					                  command: npm install --force --global yarn@1.22.0
 | 
				
			||||||
            - run:
 | 
					            - run:
 | 
				
			||||||
                  name: yarn
 | 
					                  name: yarn
 | 
				
			||||||
                  command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
 | 
					                  command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
 | 
				
			||||||
            - setup_remote_docker
 | 
					            - setup_remote_docker
 | 
				
			||||||
            - run: yarn build:ci
 | 
					            - run: yarn build:ci || yarn build:ci || yarn build:ci
 | 
				
			||||||
            - run: yarn build:ts
 | 
					            - run: yarn build:ts || yarn build:ts || yarn build:ts
 | 
				
			||||||
            - save_cache:
 | 
					            - save_cache:
 | 
				
			||||||
                  key: repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
					                  key: repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
				
			||||||
                  paths:
 | 
					                  paths:
 | 
				
			||||||
@@ -31,57 +31,59 @@ jobs:
 | 
				
			|||||||
    test-exchange-ganache:
 | 
					    test-exchange-ganache:
 | 
				
			||||||
        resource_class: medium+
 | 
					        resource_class: medium+
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
            - restore_cache:
 | 
					            - restore_cache:
 | 
				
			||||||
                  keys:
 | 
					                  keys:
 | 
				
			||||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
					                      - 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:
 | 
					    test-integrations-ganache:
 | 
				
			||||||
        resource_class: medium+
 | 
					        resource_class: medium+
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
            - restore_cache:
 | 
					            - restore_cache:
 | 
				
			||||||
                  keys:
 | 
					                  keys:
 | 
				
			||||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
					                      - 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:
 | 
					    test-contracts-staking-ganache:
 | 
				
			||||||
        resource_class: medium+
 | 
					        resource_class: medium+
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
            - restore_cache:
 | 
					            - restore_cache:
 | 
				
			||||||
                  keys:
 | 
					                  keys:
 | 
				
			||||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
					                      - 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:
 | 
					    test-contracts-extra-ganache:
 | 
				
			||||||
        resource_class: medium+
 | 
					        resource_class: medium+
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
            - restore_cache:
 | 
					            - restore_cache:
 | 
				
			||||||
                  keys:
 | 
					                  keys:
 | 
				
			||||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
					                      - 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:
 | 
					    test-contracts-rest-ganache:
 | 
				
			||||||
        resource_class: medium+
 | 
					        resource_class: medium+
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
            - restore_cache:
 | 
					            - restore_cache:
 | 
				
			||||||
                  keys:
 | 
					                  keys:
 | 
				
			||||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
					                      - 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:
 | 
					    test-publish:
 | 
				
			||||||
        resource_class: medium+
 | 
					        resource_class: large
 | 
				
			||||||
 | 
					        environment:
 | 
				
			||||||
 | 
					            NODE_OPTIONS: '--max-old-space-size=6442'
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
            - image: 0xorg/verdaccio
 | 
					            - image: 0xorg/verdaccio
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
@@ -95,7 +97,7 @@ jobs:
 | 
				
			|||||||
                  path: ~/.npm/_logs
 | 
					                  path: ~/.npm/_logs
 | 
				
			||||||
    test-doc-generation:
 | 
					    test-doc-generation:
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
            - restore_cache:
 | 
					            - restore_cache:
 | 
				
			||||||
@@ -106,18 +108,18 @@ jobs:
 | 
				
			|||||||
                  no_output_timeout: 1200
 | 
					                  no_output_timeout: 1200
 | 
				
			||||||
    test-rest:
 | 
					    test-rest:
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
            - restore_cache:
 | 
					            - restore_cache:
 | 
				
			||||||
                  keys:
 | 
					                  keys:
 | 
				
			||||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
					                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
				
			||||||
            - run: yarn wsrun test:circleci @0x/contracts-test-utils
 | 
					            - run: yarn wsrun -p @0x/contracts-test-utils -m --serial -c test:circleci
 | 
				
			||||||
            - run: yarn wsrun test:circleci @0x/contract-artifacts
 | 
					            - run: yarn wsrun -p @0x/contract-artifacts -m --serial -c test:circleci
 | 
				
			||||||
            - run: yarn wsrun test:circleci @0x/contract-wrappers-test
 | 
					            - run: yarn wsrun -p @0x/contract-wrappers-test -m --serial -c test:circleci
 | 
				
			||||||
            - run: yarn wsrun test:circleci @0x/migrations
 | 
					            - run: yarn wsrun -p @0x/migrations -m --serial -c test:circleci
 | 
				
			||||||
            - run: yarn wsrun test:circleci @0x/order-utils
 | 
					            - run: yarn wsrun -p @0x/order-utils -m --serial -c test:circleci
 | 
				
			||||||
            - run: yarn wsrun test:circleci @0x/asset-swapper
 | 
					            - run: yarn wsrun -p @0x/asset-swapper -m --serial -c test:circleci
 | 
				
			||||||
            - save_cache:
 | 
					            - save_cache:
 | 
				
			||||||
                  key: coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
 | 
					                  key: coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
 | 
				
			||||||
                  paths:
 | 
					                  paths:
 | 
				
			||||||
@@ -134,7 +136,7 @@ jobs:
 | 
				
			|||||||
        resource_class: large
 | 
					        resource_class: large
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
            - restore_cache:
 | 
					            - restore_cache:
 | 
				
			||||||
                  keys:
 | 
					                  keys:
 | 
				
			||||||
@@ -145,7 +147,7 @@ jobs:
 | 
				
			|||||||
            - run: yarn diff_md_docs:ci
 | 
					            - run: yarn diff_md_docs:ci
 | 
				
			||||||
    submit-coverage:
 | 
					    submit-coverage:
 | 
				
			||||||
        docker:
 | 
					        docker:
 | 
				
			||||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
					            - image: node:12
 | 
				
			||||||
        working_directory: ~/repo
 | 
					        working_directory: ~/repo
 | 
				
			||||||
        steps:
 | 
					        steps:
 | 
				
			||||||
            - restore_cache:
 | 
					            - restore_cache:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
								
							@@ -7,6 +7,9 @@ on:
 | 
				
			|||||||
              description: 'required CI status'
 | 
					              description: 'required CI status'
 | 
				
			||||||
              default: 'success'
 | 
					              default: 'success'
 | 
				
			||||||
              required: true
 | 
					              required: true
 | 
				
			||||||
 | 
					          prerelease:
 | 
				
			||||||
 | 
					              description: 'prerelease name'
 | 
				
			||||||
 | 
					              required: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
    publish:
 | 
					    publish:
 | 
				
			||||||
@@ -21,7 +24,7 @@ jobs:
 | 
				
			|||||||
                  (echo "::error ::${{ github.ref }} does not have a successful CI status" && false)
 | 
					                  (echo "::error ::${{ github.ref }} does not have a successful CI status" && false)
 | 
				
			||||||
            - uses: actions/checkout@v2
 | 
					            - uses: actions/checkout@v2
 | 
				
			||||||
              with:
 | 
					              with:
 | 
				
			||||||
                ref: 'development'
 | 
					                ref: ${{ github.ref }}
 | 
				
			||||||
                fetch-depth: 0
 | 
					                fetch-depth: 0
 | 
				
			||||||
            - uses: actions/setup-node@v1
 | 
					            - uses: actions/setup-node@v1
 | 
				
			||||||
              with:
 | 
					              with:
 | 
				
			||||||
@@ -41,7 +44,9 @@ jobs:
 | 
				
			|||||||
              env:
 | 
					              env:
 | 
				
			||||||
                  NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
 | 
					                  NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
 | 
				
			||||||
                  GITHUB_TOKEN: ${{ github.token }}
 | 
					                  GITHUB_TOKEN: ${{ github.token }}
 | 
				
			||||||
 | 
					                  PUBLISH_PRERELEASE: ${{ github.event.inputs.prerelease }}
 | 
				
			||||||
            - name: 'merge into main branch'
 | 
					            - name: 'merge into main branch'
 | 
				
			||||||
 | 
					              if: github.event.inputs.prerelease == '' # unless it's a prerelease
 | 
				
			||||||
              run: |
 | 
					              run: |
 | 
				
			||||||
                  git checkout main && \
 | 
					                  git checkout main && \
 | 
				
			||||||
                  git merge ${{ github.ref }} && \
 | 
					                  git merge ${{ github.ref }} && \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "3.7.11",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "3.7.10",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "3.7.9",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "3.7.8",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "3.7.7",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "3.7.6",
 | 
					        "version": "3.7.6",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.7.11 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.7.10 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.7.9 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.7.8 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.7.7 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v3.7.6 - _February 10, 2021_
 | 
					## v3.7.6 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-asset-proxy",
 | 
					    "name": "@0x/contracts-asset-proxy",
 | 
				
			||||||
    "version": "3.7.6",
 | 
					    "version": "3.7.11",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -51,15 +51,15 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contract-wrappers": "^13.12.3",
 | 
					        "@0x/contract-wrappers": "^13.16.1",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -67,7 +67,7 @@
 | 
				
			|||||||
        "chai-as-promised": "^7.1.0",
 | 
					        "chai-as-promised": "^7.1.0",
 | 
				
			||||||
        "chai-bignumber": "^3.0.0",
 | 
					        "chai-bignumber": "^3.0.0",
 | 
				
			||||||
        "dirty-chai": "^2.0.1",
 | 
					        "dirty-chai": "^2.0.1",
 | 
				
			||||||
        "ethereumjs-util": "^5.1.1",
 | 
					        "ethereumjs-util": "^7.0.10",
 | 
				
			||||||
        "make-promises-safe": "^1.1.0",
 | 
					        "make-promises-safe": "^1.1.0",
 | 
				
			||||||
        "mocha": "^6.2.0",
 | 
					        "mocha": "^6.2.0",
 | 
				
			||||||
        "npm-run-all": "^4.1.2",
 | 
					        "npm-run-all": "^4.1.2",
 | 
				
			||||||
@@ -76,20 +76,20 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/contracts-erc1155": "^2.1.24",
 | 
					        "@0x/contracts-erc1155": "^2.1.29",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-erc721": "^3.1.24",
 | 
					        "@0x/contracts-erc721": "^3.1.29",
 | 
				
			||||||
        "@0x/contracts-exchange-libs": "^4.3.24",
 | 
					        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "lodash": "^4.17.11"
 | 
					        "lodash": "^4.17.11"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,354 +0,0 @@
 | 
				
			|||||||
import { ContractTxFunctionObj } from '@0x/contract-wrappers';
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
    blockchainTests,
 | 
					 | 
				
			||||||
    constants,
 | 
					 | 
				
			||||||
    expect,
 | 
					 | 
				
			||||||
    filterLogsToArguments,
 | 
					 | 
				
			||||||
    getRandomInteger,
 | 
					 | 
				
			||||||
    randomAddress,
 | 
					 | 
				
			||||||
    shortZip,
 | 
					 | 
				
			||||||
} from '@0x/contracts-test-utils';
 | 
					 | 
				
			||||||
import { BigNumber, hexUtils, NULL_ADDRESS } from '@0x/utils';
 | 
					 | 
				
			||||||
import { DecodedLogs } from 'ethereum-types';
 | 
					 | 
				
			||||||
import * as _ from 'lodash';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { DexForwarderBridgeCall, dexForwarderBridgeDataEncoder } from '../src/dex_forwarder_bridge';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { artifacts } from './artifacts';
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
    TestDexForwarderBridgeBridgeTransferFromCalledEventArgs as BtfCalledEventArgs,
 | 
					 | 
				
			||||||
    TestDexForwarderBridgeContract,
 | 
					 | 
				
			||||||
    TestDexForwarderBridgeEvents as TestEvents,
 | 
					 | 
				
			||||||
} from './wrappers';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const { ZERO_AMOUNT } = constants;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
blockchainTests.resets('DexForwarderBridge unit tests', env => {
 | 
					 | 
				
			||||||
    let testContract: TestDexForwarderBridgeContract;
 | 
					 | 
				
			||||||
    let inputToken: string;
 | 
					 | 
				
			||||||
    let outputToken: string;
 | 
					 | 
				
			||||||
    const BRIDGE_SUCCESS = '0xdc1600f3';
 | 
					 | 
				
			||||||
    const BRIDGE_FAILURE = '0xffffffff';
 | 
					 | 
				
			||||||
    const BRIDGE_REVERT_ERROR = 'oopsie';
 | 
					 | 
				
			||||||
    const NOT_AUTHORIZED_REVERT = 'DexForwarderBridge/SENDER_NOT_AUTHORIZED';
 | 
					 | 
				
			||||||
    const DEFAULTS = {
 | 
					 | 
				
			||||||
        toAddress: randomAddress(),
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    before(async () => {
 | 
					 | 
				
			||||||
        testContract = await TestDexForwarderBridgeContract.deployFrom0xArtifactAsync(
 | 
					 | 
				
			||||||
            artifacts.TestDexForwarderBridge,
 | 
					 | 
				
			||||||
            env.provider,
 | 
					 | 
				
			||||||
            env.txDefaults,
 | 
					 | 
				
			||||||
            artifacts,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        // Create test tokens.
 | 
					 | 
				
			||||||
        [inputToken, outputToken] = [
 | 
					 | 
				
			||||||
            await callAndTransactAsync(testContract.createToken()),
 | 
					 | 
				
			||||||
            await callAndTransactAsync(testContract.createToken()),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
        await callAndTransactAsync(testContract.setAuthorized(env.txDefaults.from as string));
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async function callAndTransactAsync<TResult>(fnCall: ContractTxFunctionObj<TResult>): Promise<TResult> {
 | 
					 | 
				
			||||||
        const result = await fnCall.callAsync();
 | 
					 | 
				
			||||||
        await fnCall.awaitTransactionSuccessAsync({}, { shouldValidate: false });
 | 
					 | 
				
			||||||
        return result;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function getRandomBridgeCall(
 | 
					 | 
				
			||||||
        bridgeAddress: string,
 | 
					 | 
				
			||||||
        fields: Partial<DexForwarderBridgeCall> = {},
 | 
					 | 
				
			||||||
    ): DexForwarderBridgeCall {
 | 
					 | 
				
			||||||
        return {
 | 
					 | 
				
			||||||
            target: bridgeAddress,
 | 
					 | 
				
			||||||
            inputTokenAmount: getRandomInteger(1, '100e18'),
 | 
					 | 
				
			||||||
            outputTokenAmount: getRandomInteger(1, '100e18'),
 | 
					 | 
				
			||||||
            bridgeData: hexUtils.leftPad(inputToken),
 | 
					 | 
				
			||||||
            ...fields,
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    describe('bridgeTransferFrom()', () => {
 | 
					 | 
				
			||||||
        let goodBridgeCalls: DexForwarderBridgeCall[];
 | 
					 | 
				
			||||||
        let revertingBridgeCall: DexForwarderBridgeCall;
 | 
					 | 
				
			||||||
        let failingBridgeCall: DexForwarderBridgeCall;
 | 
					 | 
				
			||||||
        let allBridgeCalls: DexForwarderBridgeCall[];
 | 
					 | 
				
			||||||
        let totalFillableOutputAmount: BigNumber;
 | 
					 | 
				
			||||||
        let totalFillableInputAmount: BigNumber;
 | 
					 | 
				
			||||||
        let recipientOutputBalance: BigNumber;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        beforeEach(async () => {
 | 
					 | 
				
			||||||
            goodBridgeCalls = [];
 | 
					 | 
				
			||||||
            for (let i = 0; i < 4; ++i) {
 | 
					 | 
				
			||||||
                goodBridgeCalls.push(await createBridgeCallAsync({ returnCode: BRIDGE_SUCCESS }));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            revertingBridgeCall = await createBridgeCallAsync({ revertError: BRIDGE_REVERT_ERROR });
 | 
					 | 
				
			||||||
            failingBridgeCall = await createBridgeCallAsync({ returnCode: BRIDGE_FAILURE });
 | 
					 | 
				
			||||||
            allBridgeCalls = _.shuffle([failingBridgeCall, revertingBridgeCall, ...goodBridgeCalls]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            totalFillableInputAmount = BigNumber.sum(...goodBridgeCalls.map(c => c.inputTokenAmount));
 | 
					 | 
				
			||||||
            totalFillableOutputAmount = BigNumber.sum(...goodBridgeCalls.map(c => c.outputTokenAmount));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Grant the taker some output tokens.
 | 
					 | 
				
			||||||
            await testContract.setTokenBalance(
 | 
					 | 
				
			||||||
                outputToken,
 | 
					 | 
				
			||||||
                DEFAULTS.toAddress,
 | 
					 | 
				
			||||||
                (recipientOutputBalance = getRandomInteger(1, '100e18')),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        async function setForwarderInputBalanceAsync(amount: BigNumber): Promise<void> {
 | 
					 | 
				
			||||||
            await testContract
 | 
					 | 
				
			||||||
                .setTokenBalance(inputToken, testContract.address, amount)
 | 
					 | 
				
			||||||
                .awaitTransactionSuccessAsync({}, { shouldValidate: false });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        async function createBridgeCallAsync(
 | 
					 | 
				
			||||||
            opts: Partial<{
 | 
					 | 
				
			||||||
                returnCode: string;
 | 
					 | 
				
			||||||
                revertError: string;
 | 
					 | 
				
			||||||
                callFields: Partial<DexForwarderBridgeCall>;
 | 
					 | 
				
			||||||
                outputFillAmount: BigNumber;
 | 
					 | 
				
			||||||
            }>,
 | 
					 | 
				
			||||||
        ): Promise<DexForwarderBridgeCall> {
 | 
					 | 
				
			||||||
            const { returnCode, revertError, callFields, outputFillAmount } = {
 | 
					 | 
				
			||||||
                returnCode: BRIDGE_SUCCESS,
 | 
					 | 
				
			||||||
                revertError: '',
 | 
					 | 
				
			||||||
                ...opts,
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            const bridge = await callAndTransactAsync(testContract.createBridge(returnCode, revertError));
 | 
					 | 
				
			||||||
            const call = getRandomBridgeCall(bridge, callFields);
 | 
					 | 
				
			||||||
            await testContract
 | 
					 | 
				
			||||||
                .setBridgeTransferAmount(call.target, outputFillAmount || call.outputTokenAmount)
 | 
					 | 
				
			||||||
                .awaitTransactionSuccessAsync({}, { shouldValidate: false });
 | 
					 | 
				
			||||||
            return call;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        async function callBridgeTransferFromAsync(opts: {
 | 
					 | 
				
			||||||
            bridgeData: string;
 | 
					 | 
				
			||||||
            sellAmount?: BigNumber;
 | 
					 | 
				
			||||||
            buyAmount?: BigNumber;
 | 
					 | 
				
			||||||
        }): Promise<DecodedLogs> {
 | 
					 | 
				
			||||||
            // Fund the forwarder with input tokens to sell.
 | 
					 | 
				
			||||||
            await setForwarderInputBalanceAsync(opts.sellAmount || totalFillableInputAmount);
 | 
					 | 
				
			||||||
            const call = testContract.bridgeTransferFrom(
 | 
					 | 
				
			||||||
                outputToken,
 | 
					 | 
				
			||||||
                testContract.address,
 | 
					 | 
				
			||||||
                DEFAULTS.toAddress,
 | 
					 | 
				
			||||||
                opts.buyAmount || totalFillableOutputAmount,
 | 
					 | 
				
			||||||
                opts.bridgeData,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            const returnCode = await call.callAsync();
 | 
					 | 
				
			||||||
            if (returnCode !== BRIDGE_SUCCESS) {
 | 
					 | 
				
			||||||
                throw new Error('Expected BRIDGE_SUCCESS');
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            const receipt = await call.awaitTransactionSuccessAsync({}, { shouldValidate: false });
 | 
					 | 
				
			||||||
            // tslint:disable-next-line: no-unnecessary-type-assertion
 | 
					 | 
				
			||||||
            return receipt.logs as DecodedLogs;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('succeeds with no bridge calls and no input balance', async () => {
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls: [],
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            await callBridgeTransferFromAsync({ bridgeData, sellAmount: ZERO_AMOUNT });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('succeeds with bridge calls and no input balance', async () => {
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls: allBridgeCalls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            await callBridgeTransferFromAsync({ bridgeData, sellAmount: ZERO_AMOUNT });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('succeeds with no bridge calls and an input balance', async () => {
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls: [],
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            await callBridgeTransferFromAsync({
 | 
					 | 
				
			||||||
                bridgeData,
 | 
					 | 
				
			||||||
                sellAmount: new BigNumber(1),
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('succeeds if entire input token balance is not consumed', async () => {
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls: allBridgeCalls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            await callBridgeTransferFromAsync({
 | 
					 | 
				
			||||||
                bridgeData,
 | 
					 | 
				
			||||||
                sellAmount: totalFillableInputAmount.plus(1),
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('fails if not authorized', async () => {
 | 
					 | 
				
			||||||
            const calls = goodBridgeCalls.slice(0, 1);
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            await callAndTransactAsync(testContract.setAuthorized(NULL_ADDRESS));
 | 
					 | 
				
			||||||
            return expect(callBridgeTransferFromAsync({ bridgeData, sellAmount: new BigNumber(1) })).to.revertWith(
 | 
					 | 
				
			||||||
                NOT_AUTHORIZED_REVERT,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('succeeds with one bridge call', async () => {
 | 
					 | 
				
			||||||
            const calls = goodBridgeCalls.slice(0, 1);
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            await callBridgeTransferFromAsync({ bridgeData, sellAmount: calls[0].inputTokenAmount });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('succeeds with many bridge calls', async () => {
 | 
					 | 
				
			||||||
            const calls = goodBridgeCalls;
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            await callBridgeTransferFromAsync({ bridgeData });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('swallows a failing bridge call', async () => {
 | 
					 | 
				
			||||||
            const calls = _.shuffle([...goodBridgeCalls, failingBridgeCall]);
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            await callBridgeTransferFromAsync({ bridgeData });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('consumes input tokens for output tokens', async () => {
 | 
					 | 
				
			||||||
            const calls = allBridgeCalls;
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            await callBridgeTransferFromAsync({ bridgeData });
 | 
					 | 
				
			||||||
            const currentBridgeInputBalance = await testContract
 | 
					 | 
				
			||||||
                .balanceOf(inputToken, testContract.address)
 | 
					 | 
				
			||||||
                .callAsync();
 | 
					 | 
				
			||||||
            expect(currentBridgeInputBalance).to.bignumber.eq(0);
 | 
					 | 
				
			||||||
            const currentRecipientOutputBalance = await testContract
 | 
					 | 
				
			||||||
                .balanceOf(outputToken, DEFAULTS.toAddress)
 | 
					 | 
				
			||||||
                .callAsync();
 | 
					 | 
				
			||||||
            expect(currentRecipientOutputBalance).to.bignumber.eq(totalFillableOutputAmount);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it("transfers only up to each call's input amount to each bridge", async () => {
 | 
					 | 
				
			||||||
            const calls = goodBridgeCalls;
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            const logs = await callBridgeTransferFromAsync({ bridgeData });
 | 
					 | 
				
			||||||
            const btfs = filterLogsToArguments<BtfCalledEventArgs>(logs, TestEvents.BridgeTransferFromCalled);
 | 
					 | 
				
			||||||
            for (const [call, btf] of shortZip(goodBridgeCalls, btfs)) {
 | 
					 | 
				
			||||||
                expect(btf.inputTokenBalance).to.bignumber.eq(call.inputTokenAmount);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('transfers only up to outstanding sell amount to each bridge', async () => {
 | 
					 | 
				
			||||||
            // Prepend an extra bridge call.
 | 
					 | 
				
			||||||
            const calls = [
 | 
					 | 
				
			||||||
                await createBridgeCallAsync({
 | 
					 | 
				
			||||||
                    callFields: {
 | 
					 | 
				
			||||||
                        inputTokenAmount: new BigNumber(1),
 | 
					 | 
				
			||||||
                        outputTokenAmount: new BigNumber(1),
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                }),
 | 
					 | 
				
			||||||
                ...goodBridgeCalls,
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            const logs = await callBridgeTransferFromAsync({ bridgeData });
 | 
					 | 
				
			||||||
            const btfs = filterLogsToArguments<BtfCalledEventArgs>(logs, TestEvents.BridgeTransferFromCalled);
 | 
					 | 
				
			||||||
            expect(btfs).to.be.length(goodBridgeCalls.length + 1);
 | 
					 | 
				
			||||||
            // The last call will receive 1 less token.
 | 
					 | 
				
			||||||
            const lastCall = calls.slice(-1)[0];
 | 
					 | 
				
			||||||
            const lastBtf = btfs.slice(-1)[0];
 | 
					 | 
				
			||||||
            expect(lastBtf.inputTokenBalance).to.bignumber.eq(lastCall.inputTokenAmount.minus(1));
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('recoups funds from a bridge that fails', async () => {
 | 
					 | 
				
			||||||
            // Prepend a call that will take the whole input amount but will
 | 
					 | 
				
			||||||
            // fail.
 | 
					 | 
				
			||||||
            const badCall = await createBridgeCallAsync({
 | 
					 | 
				
			||||||
                callFields: { inputTokenAmount: totalFillableInputAmount },
 | 
					 | 
				
			||||||
                returnCode: BRIDGE_FAILURE,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            const calls = [badCall, ...goodBridgeCalls];
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            const logs = await callBridgeTransferFromAsync({ bridgeData });
 | 
					 | 
				
			||||||
            const btfs = filterLogsToArguments<BtfCalledEventArgs>(logs, TestEvents.BridgeTransferFromCalled);
 | 
					 | 
				
			||||||
            expect(btfs).to.be.length(goodBridgeCalls.length);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('recoups funds from a bridge that reverts', async () => {
 | 
					 | 
				
			||||||
            // Prepend a call that will take the whole input amount but will
 | 
					 | 
				
			||||||
            // revert.
 | 
					 | 
				
			||||||
            const badCall = await createBridgeCallAsync({
 | 
					 | 
				
			||||||
                callFields: { inputTokenAmount: totalFillableInputAmount },
 | 
					 | 
				
			||||||
                revertError: BRIDGE_REVERT_ERROR,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            const calls = [badCall, ...goodBridgeCalls];
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            const logs = await callBridgeTransferFromAsync({ bridgeData });
 | 
					 | 
				
			||||||
            const btfs = filterLogsToArguments<BtfCalledEventArgs>(logs, TestEvents.BridgeTransferFromCalled);
 | 
					 | 
				
			||||||
            expect(btfs).to.be.length(goodBridgeCalls.length);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('recoups funds from a bridge that under-pays', async () => {
 | 
					 | 
				
			||||||
            // Prepend a call that will take the whole input amount but will
 | 
					 | 
				
			||||||
            // underpay the output amount..
 | 
					 | 
				
			||||||
            const badCall = await createBridgeCallAsync({
 | 
					 | 
				
			||||||
                callFields: {
 | 
					 | 
				
			||||||
                    inputTokenAmount: totalFillableInputAmount,
 | 
					 | 
				
			||||||
                    outputTokenAmount: new BigNumber(2),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                outputFillAmount: new BigNumber(1),
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            const calls = [badCall, ...goodBridgeCalls];
 | 
					 | 
				
			||||||
            const bridgeData = dexForwarderBridgeDataEncoder.encode({
 | 
					 | 
				
			||||||
                inputToken,
 | 
					 | 
				
			||||||
                calls,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            const logs = await callBridgeTransferFromAsync({ bridgeData });
 | 
					 | 
				
			||||||
            const btfs = filterLogsToArguments<BtfCalledEventArgs>(logs, TestEvents.BridgeTransferFromCalled);
 | 
					 | 
				
			||||||
            expect(btfs).to.be.length(goodBridgeCalls.length);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    describe('executeBridgeCall()', () => {
 | 
					 | 
				
			||||||
        it('cannot be called externally', async () => {
 | 
					 | 
				
			||||||
            return expect(
 | 
					 | 
				
			||||||
                testContract
 | 
					 | 
				
			||||||
                    .executeBridgeCall(
 | 
					 | 
				
			||||||
                        randomAddress(),
 | 
					 | 
				
			||||||
                        randomAddress(),
 | 
					 | 
				
			||||||
                        randomAddress(),
 | 
					 | 
				
			||||||
                        randomAddress(),
 | 
					 | 
				
			||||||
                        new BigNumber(1),
 | 
					 | 
				
			||||||
                        new BigNumber(1),
 | 
					 | 
				
			||||||
                        constants.NULL_BYTES,
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                    .callAsync(),
 | 
					 | 
				
			||||||
            ).to.revertWith('DexForwarderBridge/ONLY_SELF');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -168,7 +168,7 @@ describe('StaticCallProxy', () => {
 | 
				
			|||||||
        it('should revert if the hash of the output is different than expected expected', async () => {
 | 
					        it('should revert if the hash of the output is different than expected expected', async () => {
 | 
				
			||||||
            const staticCallData = staticCallTarget.isOddNumber(new BigNumber(0)).getABIEncodedTransactionData();
 | 
					            const staticCallData = staticCallTarget.isOddNumber(new BigNumber(0)).getABIEncodedTransactionData();
 | 
				
			||||||
            const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
 | 
					            const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
 | 
				
			||||||
            const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
 | 
					            const expectedResultHash = ethUtil.bufferToHex(ethUtil.keccak256(trueAsBuffer));
 | 
				
			||||||
            const assetData = assetDataInterface
 | 
					            const assetData = assetDataInterface
 | 
				
			||||||
                .StaticCall(staticCallTarget.address, staticCallData, expectedResultHash)
 | 
					                .StaticCall(staticCallTarget.address, staticCallData, expectedResultHash)
 | 
				
			||||||
                .getABIEncodedTransactionData();
 | 
					                .getABIEncodedTransactionData();
 | 
				
			||||||
@@ -199,7 +199,7 @@ describe('StaticCallProxy', () => {
 | 
				
			|||||||
        it('should be successful if a function call with one static input returns the correct value', async () => {
 | 
					        it('should be successful if a function call with one static input returns the correct value', async () => {
 | 
				
			||||||
            const staticCallData = staticCallTarget.isOddNumber(new BigNumber(1)).getABIEncodedTransactionData();
 | 
					            const staticCallData = staticCallTarget.isOddNumber(new BigNumber(1)).getABIEncodedTransactionData();
 | 
				
			||||||
            const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
 | 
					            const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
 | 
				
			||||||
            const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
 | 
					            const expectedResultHash = ethUtil.bufferToHex(ethUtil.keccak256(trueAsBuffer));
 | 
				
			||||||
            const assetData = assetDataInterface
 | 
					            const assetData = assetDataInterface
 | 
				
			||||||
                .StaticCall(staticCallTarget.address, staticCallData, expectedResultHash)
 | 
					                .StaticCall(staticCallTarget.address, staticCallData, expectedResultHash)
 | 
				
			||||||
                .getABIEncodedTransactionData();
 | 
					                .getABIEncodedTransactionData();
 | 
				
			||||||
@@ -232,7 +232,7 @@ describe('StaticCallProxy', () => {
 | 
				
			|||||||
            const offset = '0000000000000000000000000000000000000000000000000000000000000020';
 | 
					            const offset = '0000000000000000000000000000000000000000000000000000000000000020';
 | 
				
			||||||
            const encodedExpectedResultWithOffset = `0x${offset}${abiEncoder.encode(expectedResults).slice(2)}`;
 | 
					            const encodedExpectedResultWithOffset = `0x${offset}${abiEncoder.encode(expectedResults).slice(2)}`;
 | 
				
			||||||
            const expectedResultHash = ethUtil.bufferToHex(
 | 
					            const expectedResultHash = ethUtil.bufferToHex(
 | 
				
			||||||
                ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)),
 | 
					                ethUtil.keccak256(ethUtil.toBuffer(encodedExpectedResultWithOffset)),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            const assetData = assetDataInterface
 | 
					            const assetData = assetDataInterface
 | 
				
			||||||
                .StaticCall(staticCallTarget.address, staticCallData, expectedResultHash)
 | 
					                .StaticCall(staticCallTarget.address, staticCallData, expectedResultHash)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "1.1.29",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "1.1.28",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "1.1.27",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "1.1.26",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "1.1.25",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "1.1.24",
 | 
					        "version": "1.1.24",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.1.29 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.1.28 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.1.27 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.1.26 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.1.25 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v1.1.24 - _February 10, 2021_
 | 
					## v1.1.24 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-broker",
 | 
					    "name": "@0x/contracts-broker",
 | 
				
			||||||
    "version": "1.1.24",
 | 
					    "version": "1.1.29",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -51,20 +51,20 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-asset-proxy": "^3.7.6",
 | 
					        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-erc721": "^3.1.24",
 | 
					        "@0x/contracts-erc721": "^3.1.29",
 | 
				
			||||||
        "@0x/contracts-exchange": "^3.2.25",
 | 
					        "@0x/contracts-exchange": "^3.2.30",
 | 
				
			||||||
        "@0x/contracts-exchange-libs": "^4.3.24",
 | 
					        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -81,14 +81,14 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "ethereum-types": "^3.4.0"
 | 
					        "ethereum-types": "^3.5.0"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
        "access": "public"
 | 
					        "access": "public"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "3.1.30",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "3.1.29",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "3.1.28",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "3.1.27",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "3.1.26",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "3.1.25",
 | 
					        "version": "3.1.25",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.1.30 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.1.29 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.1.28 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.1.27 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.1.26 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v3.1.25 - _February 10, 2021_
 | 
					## v3.1.25 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-coordinator",
 | 
					    "name": "@0x/contracts-coordinator",
 | 
				
			||||||
    "version": "3.1.25",
 | 
					    "version": "3.1.30",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -52,17 +52,17 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-asset-proxy": "^3.7.6",
 | 
					        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
				
			||||||
        "@0x/contracts-dev-utils": "^1.3.23",
 | 
					        "@0x/contracts-dev-utils": "^1.3.28",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -79,20 +79,20 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/assert": "^3.0.21",
 | 
					        "@0x/assert": "^3.0.27",
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/contract-addresses": "^5.10.0",
 | 
					        "@0x/contract-addresses": "^6.1.0",
 | 
				
			||||||
        "@0x/contracts-exchange": "^3.2.25",
 | 
					        "@0x/contracts-exchange": "^3.2.30",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/json-schemas": "^5.4.1",
 | 
					        "@0x/json-schemas": "^6.1.3",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "http-status-codes": "^1.3.2"
 | 
					        "http-status-codes": "^1.3.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,4 @@
 | 
				
			|||||||
import { assert as sharedAssert } from '@0x/assert';
 | 
					import { assert as sharedAssert } from '@0x/assert';
 | 
				
			||||||
// HACK: We need those two unused imports because they're actually used by sharedAssert which gets injected here
 | 
					 | 
				
			||||||
import { Schema } from '@0x/json-schemas'; // tslint:disable-line:no-unused-variable
 | 
					 | 
				
			||||||
import { Order } from '@0x/types'; // tslint:disable-line:no-unused-variable
 | 
					 | 
				
			||||||
import { BigNumber } from '@0x/utils'; // tslint:disable-line:no-unused-variable
 | 
					 | 
				
			||||||
import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const assert = {
 | 
					export const assert = {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "1.3.28",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "1.3.27",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "1.3.26",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "1.3.25",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "1.3.24",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "1.3.23",
 | 
					        "version": "1.3.23",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.3.28 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.3.27 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.3.26 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.3.25 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.3.24 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v1.3.23 - _February 10, 2021_
 | 
					## v1.3.23 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-dev-utils",
 | 
					    "name": "@0x/contracts-dev-utils",
 | 
				
			||||||
    "version": "1.3.23",
 | 
					    "version": "1.3.28",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -41,18 +41,18 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/dev-utils",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/dev-utils",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/assert": "^3.0.21",
 | 
					        "@0x/assert": "^3.0.27",
 | 
				
			||||||
        "@0x/contracts-asset-proxy": "^3.7.6",
 | 
					        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "ethers": "~4.0.4",
 | 
					        "ethers": "~4.0.4",
 | 
				
			||||||
        "npm-run-all": "^4.1.2",
 | 
					        "npm-run-all": "^4.1.2",
 | 
				
			||||||
        "shx": "^0.2.2",
 | 
					        "shx": "^0.2.2",
 | 
				
			||||||
@@ -60,10 +60,10 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@types/node": "12.12.54"
 | 
					        "@types/node": "12.12.54"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "2.1.29",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "2.1.28",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "2.1.27",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "2.1.26",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "2.1.25",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "2.1.24",
 | 
					        "version": "2.1.24",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v2.1.29 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v2.1.28 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v2.1.27 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v2.1.26 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v2.1.25 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v2.1.24 - _February 10, 2021_
 | 
					## v2.1.24 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-erc1155",
 | 
					    "name": "@0x/contracts-erc1155",
 | 
				
			||||||
    "version": "2.1.24",
 | 
					    "version": "2.1.29",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -52,15 +52,15 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -68,7 +68,7 @@
 | 
				
			|||||||
        "chai-as-promised": "^7.1.0",
 | 
					        "chai-as-promised": "^7.1.0",
 | 
				
			||||||
        "chai-bignumber": "^3.0.0",
 | 
					        "chai-bignumber": "^3.0.0",
 | 
				
			||||||
        "dirty-chai": "^2.0.1",
 | 
					        "dirty-chai": "^2.0.1",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "make-promises-safe": "^1.1.0",
 | 
					        "make-promises-safe": "^1.1.0",
 | 
				
			||||||
        "mocha": "^6.2.0",
 | 
					        "mocha": "^6.2.0",
 | 
				
			||||||
        "npm-run-all": "^4.1.2",
 | 
					        "npm-run-all": "^4.1.2",
 | 
				
			||||||
@@ -77,13 +77,13 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "lodash": "^4.17.11"
 | 
					        "lodash": "^4.17.11"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "3.3.8",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "3.3.7",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "3.3.6",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "3.3.5",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "3.3.4",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "3.3.3",
 | 
					        "version": "3.3.3",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.3.8 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.3.7 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.3.6 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.3.5 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.3.4 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v3.3.3 - _February 10, 2021_
 | 
					## v3.3.3 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-erc20",
 | 
					    "name": "@0x/contracts-erc20",
 | 
				
			||||||
    "version": "3.3.3",
 | 
					    "version": "3.3.8",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -51,18 +51,18 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -70,7 +70,7 @@
 | 
				
			|||||||
        "chai-as-promised": "^7.1.0",
 | 
					        "chai-as-promised": "^7.1.0",
 | 
				
			||||||
        "chai-bignumber": "^3.0.0",
 | 
					        "chai-bignumber": "^3.0.0",
 | 
				
			||||||
        "dirty-chai": "^2.0.1",
 | 
					        "dirty-chai": "^2.0.1",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "lodash": "^4.17.11",
 | 
					        "lodash": "^4.17.11",
 | 
				
			||||||
        "make-promises-safe": "^1.1.0",
 | 
					        "make-promises-safe": "^1.1.0",
 | 
				
			||||||
        "mocha": "^6.2.0",
 | 
					        "mocha": "^6.2.0",
 | 
				
			||||||
@@ -79,10 +79,10 @@
 | 
				
			|||||||
        "solhint": "^1.4.1",
 | 
					        "solhint": "^1.4.1",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18"
 | 
					        "@0x/base-contract": "^6.4.0"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
        "access": "public"
 | 
					        "access": "public"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ export {
 | 
				
			|||||||
    WETH9Events,
 | 
					    WETH9Events,
 | 
				
			||||||
    WETH9DepositEventArgs,
 | 
					    WETH9DepositEventArgs,
 | 
				
			||||||
    WETH9TransferEventArgs,
 | 
					    WETH9TransferEventArgs,
 | 
				
			||||||
 | 
					    WETH9WithdrawalEventArgs,
 | 
				
			||||||
    ZRXTokenContract,
 | 
					    ZRXTokenContract,
 | 
				
			||||||
    DummyERC20TokenTransferEventArgs,
 | 
					    DummyERC20TokenTransferEventArgs,
 | 
				
			||||||
    ERC20TokenEventArgs,
 | 
					    ERC20TokenEventArgs,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,8 +39,8 @@ describe('EtherToken', () => {
 | 
				
			|||||||
            artifacts.WETH9,
 | 
					            artifacts.WETH9,
 | 
				
			||||||
            provider,
 | 
					            provider,
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                gasPrice,
 | 
					 | 
				
			||||||
                ...txDefaults,
 | 
					                ...txDefaults,
 | 
				
			||||||
 | 
					                gasPrice,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            artifacts,
 | 
					            artifacts,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "3.1.29",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "3.1.28",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "3.1.27",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "3.1.26",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "3.1.25",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "3.1.24",
 | 
					        "version": "3.1.24",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.1.29 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.1.28 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.1.27 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.1.26 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.1.25 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v3.1.24 - _February 10, 2021_
 | 
					## v3.1.24 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-erc721",
 | 
					    "name": "@0x/contracts-erc721",
 | 
				
			||||||
    "version": "3.1.24",
 | 
					    "version": "3.1.29",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -52,18 +52,18 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -71,7 +71,7 @@
 | 
				
			|||||||
        "chai-as-promised": "^7.1.0",
 | 
					        "chai-as-promised": "^7.1.0",
 | 
				
			||||||
        "chai-bignumber": "^3.0.0",
 | 
					        "chai-bignumber": "^3.0.0",
 | 
				
			||||||
        "dirty-chai": "^2.0.1",
 | 
					        "dirty-chai": "^2.0.1",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "lodash": "^4.17.11",
 | 
					        "lodash": "^4.17.11",
 | 
				
			||||||
        "make-promises-safe": "^1.1.0",
 | 
					        "make-promises-safe": "^1.1.0",
 | 
				
			||||||
        "mocha": "^6.2.0",
 | 
					        "mocha": "^6.2.0",
 | 
				
			||||||
@@ -81,10 +81,10 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18"
 | 
					        "@0x/base-contract": "^6.4.0"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
        "access": "public"
 | 
					        "access": "public"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "4.2.30",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "4.2.29",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "4.2.28",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "4.2.27",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "4.2.26",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "4.2.25",
 | 
					        "version": "4.2.25",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.2.30 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.2.29 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.2.28 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.2.27 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.2.26 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v4.2.25 - _February 10, 2021_
 | 
					## v4.2.25 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-exchange-forwarder",
 | 
					    "name": "@0x/contracts-exchange-forwarder",
 | 
				
			||||||
    "version": "4.2.25",
 | 
					    "version": "4.2.30",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -52,25 +52,25 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-asset-proxy": "^3.7.6",
 | 
					        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
				
			||||||
        "@0x/contracts-dev-utils": "^1.3.23",
 | 
					        "@0x/contracts-dev-utils": "^1.3.28",
 | 
				
			||||||
        "@0x/contracts-erc1155": "^2.1.24",
 | 
					        "@0x/contracts-erc1155": "^2.1.29",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-erc721": "^3.1.24",
 | 
					        "@0x/contracts-erc721": "^3.1.29",
 | 
				
			||||||
        "@0x/contracts-exchange": "^3.2.25",
 | 
					        "@0x/contracts-exchange": "^3.2.30",
 | 
				
			||||||
        "@0x/contracts-exchange-libs": "^4.3.24",
 | 
					        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -87,12 +87,12 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "ethereum-types": "^3.4.0"
 | 
					        "ethereum-types": "^3.5.0"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
        "access": "public"
 | 
					        "access": "public"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "4.3.29",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "4.3.28",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "4.3.27",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "4.3.26",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "4.3.25",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "4.3.24",
 | 
					        "version": "4.3.24",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.3.29 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.3.28 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.3.27 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.3.26 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.3.25 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v4.3.24 - _February 10, 2021_
 | 
					## v4.3.24 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-exchange-libs",
 | 
					    "name": "@0x/contracts-exchange-libs",
 | 
				
			||||||
    "version": "4.3.24",
 | 
					    "version": "4.3.29",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -52,14 +52,14 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/libs",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/libs",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/subproviders": "^6.4.1",
 | 
					        "@0x/subproviders": "^6.5.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -67,7 +67,7 @@
 | 
				
			|||||||
        "chai-as-promised": "^7.1.0",
 | 
					        "chai-as-promised": "^7.1.0",
 | 
				
			||||||
        "chai-bignumber": "^3.0.0",
 | 
					        "chai-bignumber": "^3.0.0",
 | 
				
			||||||
        "dirty-chai": "^2.0.1",
 | 
					        "dirty-chai": "^2.0.1",
 | 
				
			||||||
        "ethereumjs-util": "^5.1.1",
 | 
					        "ethereumjs-util": "^7.0.10",
 | 
				
			||||||
        "lodash": "^4.17.11",
 | 
					        "lodash": "^4.17.11",
 | 
				
			||||||
        "make-promises-safe": "^1.1.0",
 | 
					        "make-promises-safe": "^1.1.0",
 | 
				
			||||||
        "mocha": "^6.2.0",
 | 
					        "mocha": "^6.2.0",
 | 
				
			||||||
@@ -77,17 +77,17 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "ethereum-types": "^3.4.0"
 | 
					        "ethereum-types": "^3.5.0"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
        "access": "public"
 | 
					        "access": "public"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "3.2.30",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "3.2.29",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "3.2.28",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "3.2.27",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "3.2.26",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "3.2.25",
 | 
					        "version": "3.2.25",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.2.30 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.2.29 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.2.28 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.2.27 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v3.2.26 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v3.2.25 - _February 10, 2021_
 | 
					## v3.2.25 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-exchange",
 | 
					    "name": "@0x/contracts-exchange",
 | 
				
			||||||
    "version": "3.2.25",
 | 
					    "version": "3.2.30",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -52,21 +52,21 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-asset-proxy": "^3.7.6",
 | 
					        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
				
			||||||
        "@0x/contracts-exchange-libs": "^4.3.24",
 | 
					        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-multisig": "^4.1.25",
 | 
					        "@0x/contracts-multisig": "^4.1.30",
 | 
				
			||||||
        "@0x/contracts-staking": "^2.0.32",
 | 
					        "@0x/contracts-staking": "^2.0.37",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -74,8 +74,8 @@
 | 
				
			|||||||
        "chai-as-promised": "^7.1.0",
 | 
					        "chai-as-promised": "^7.1.0",
 | 
				
			||||||
        "chai-bignumber": "^3.0.0",
 | 
					        "chai-bignumber": "^3.0.0",
 | 
				
			||||||
        "dirty-chai": "^2.0.1",
 | 
					        "dirty-chai": "^2.0.1",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "ethereumjs-util": "^5.1.1",
 | 
					        "ethereumjs-util": "^7.0.10",
 | 
				
			||||||
        "js-combinatorics": "^0.5.3",
 | 
					        "js-combinatorics": "^0.5.3",
 | 
				
			||||||
        "make-promises-safe": "^1.1.0",
 | 
					        "make-promises-safe": "^1.1.0",
 | 
				
			||||||
        "mocha": "^6.2.0",
 | 
					        "mocha": "^6.2.0",
 | 
				
			||||||
@@ -85,16 +85,16 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/contracts-dev-utils": "^1.3.23",
 | 
					        "@0x/contracts-dev-utils": "^1.3.28",
 | 
				
			||||||
        "@0x/contracts-erc1155": "^2.1.24",
 | 
					        "@0x/contracts-erc1155": "^2.1.29",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-erc721": "^3.1.24",
 | 
					        "@0x/contracts-erc721": "^3.1.29",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "lodash": "^4.17.11"
 | 
					        "lodash": "^4.17.11"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -86,7 +86,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const SIGNATURE_LENGTH = 65;
 | 
					    const SIGNATURE_LENGTH = 65;
 | 
				
			||||||
    const generateRandomSignature = (): string => hexUtils.random(SIGNATURE_LENGTH);
 | 
					    const generateRandomSignature = (): string => hexUtils.random(SIGNATURE_LENGTH);
 | 
				
			||||||
    const hashBytes = (bytesHex: string): string => ethUtil.bufferToHex(ethUtil.sha3(ethUtil.toBuffer(bytesHex)));
 | 
					    const hashBytes = (bytesHex: string): string => hexUtils.hash(bytesHex);
 | 
				
			||||||
    const signDataHex = (dataHex: string, privateKey: Buffer): string => {
 | 
					    const signDataHex = (dataHex: string, privateKey: Buffer): string => {
 | 
				
			||||||
        const ecSignature = ethUtil.ecsign(ethUtil.toBuffer(dataHex), privateKey);
 | 
					        const ecSignature = ethUtil.ecsign(ethUtil.toBuffer(dataHex), privateKey);
 | 
				
			||||||
        return hexUtils.concat(ecSignature.v, ecSignature.r, ecSignature.s);
 | 
					        return hexUtils.concat(ecSignature.v, ecSignature.r, ecSignature.s);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,12 +12,12 @@ export abstract class AbstractBalanceAndProxyAllowanceFetcher {
 | 
				
			|||||||
     * @param userAddress Ethereum address for which to fetch the balance
 | 
					     * @param userAddress Ethereum address for which to fetch the balance
 | 
				
			||||||
     * @return Balance amount in base units
 | 
					     * @return Balance amount in base units
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public abstract async getBalanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
 | 
					    public abstract getBalanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get the 0x asset proxy allowance of assetData for userAddress
 | 
					     * Get the 0x asset proxy allowance of assetData for userAddress
 | 
				
			||||||
     * @param assetData AssetData for which to fetch the allowance
 | 
					     * @param assetData AssetData for which to fetch the allowance
 | 
				
			||||||
     * @param userAddress Ethereum address for which to fetch the allowance
 | 
					     * @param userAddress Ethereum address for which to fetch the allowance
 | 
				
			||||||
     * @return Allowance amount in base units
 | 
					     * @return Allowance amount in base units
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public abstract async getProxyAllowanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
 | 
					    public abstract getProxyAllowanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
import { BigNumber } from '@0x/utils';
 | 
					import { BigNumber } from '@0x/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export abstract class AbstractBalanceAndProxyAllowanceLazyStore {
 | 
					export abstract class AbstractBalanceAndProxyAllowanceLazyStore {
 | 
				
			||||||
    public abstract async getBalanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
 | 
					    public abstract getBalanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
 | 
				
			||||||
    public abstract async getProxyAllowanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
 | 
					    public abstract getProxyAllowanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
 | 
				
			||||||
    public abstract setBalance(assetData: string, userAddress: string, balance: BigNumber): void;
 | 
					    public abstract setBalance(assetData: string, userAddress: string, balance: BigNumber): void;
 | 
				
			||||||
    public abstract deleteBalance(assetData: string, userAddress: string): void;
 | 
					    public abstract deleteBalance(assetData: string, userAddress: string): void;
 | 
				
			||||||
    public abstract setProxyAllowance(assetData: string, userAddress: string, proxyAllowance: BigNumber): void;
 | 
					    public abstract setProxyAllowance(assetData: string, userAddress: string, proxyAllowance: BigNumber): void;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,5 +11,5 @@ export abstract class AbstractOrderFilledCancelledFetcher {
 | 
				
			|||||||
     * @param orderHash OrderHash of order we are interested in
 | 
					     * @param orderHash OrderHash of order we are interested in
 | 
				
			||||||
     * @return FilledTakerAmount
 | 
					     * @return FilledTakerAmount
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public abstract async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber>;
 | 
					    public abstract getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import { BigNumber } from '@0x/utils';
 | 
					import { BigNumber } from '@0x/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export abstract class AbstractOrderFilledCancelledLazyStore {
 | 
					export abstract class AbstractOrderFilledCancelledLazyStore {
 | 
				
			||||||
    public abstract async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber>;
 | 
					    public abstract getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber>;
 | 
				
			||||||
    public abstract setFilledTakerAmount(orderHash: string, balance: BigNumber): void;
 | 
					    public abstract setFilledTakerAmount(orderHash: string, balance: BigNumber): void;
 | 
				
			||||||
    public abstract deleteFilledTakerAmount(orderHash: string): void;
 | 
					    public abstract deleteFilledTakerAmount(orderHash: string): void;
 | 
				
			||||||
    public abstract setIsCancelled(orderHash: string, isCancelled: boolean): void;
 | 
					    public abstract setIsCancelled(orderHash: string, isCancelled: boolean): void;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ import {
 | 
				
			|||||||
    IsolatedExchangeFillEventArgs as FillEventArgs,
 | 
					    IsolatedExchangeFillEventArgs as FillEventArgs,
 | 
				
			||||||
} from '../wrappers';
 | 
					} from '../wrappers';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { Order } from '@0x/types';
 | 
				
			||||||
export interface AssetBalances {
 | 
					export interface AssetBalances {
 | 
				
			||||||
    [assetData: string]: { [address: string]: BigNumber };
 | 
					    [assetData: string]: { [address: string]: BigNumber };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -27,7 +28,6 @@ export interface IsolatedExchangeEvents {
 | 
				
			|||||||
    transferFromCalls: DispatchTransferFromCallArgs[];
 | 
					    transferFromCalls: DispatchTransferFromCallArgs[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Order = Order;
 | 
					 | 
				
			||||||
export type Numberish = string | number | BigNumber;
 | 
					export type Numberish = string | number | BigNumber;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const DEFAULT_GOOD_SIGNATURE = createGoodSignature();
 | 
					export const DEFAULT_GOOD_SIGNATURE = createGoodSignature();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,6 @@ import { ReferenceFunctions as UtilReferenceFunctions, SafeMathRevertErrors } fr
 | 
				
			|||||||
import { FillResults, Order } from '@0x/types';
 | 
					import { FillResults, Order } from '@0x/types';
 | 
				
			||||||
import { AnyRevertError, BigNumber, ExchangeRevertErrors, hexUtils, StringRevertError } from '@0x/utils';
 | 
					import { AnyRevertError, BigNumber, ExchangeRevertErrors, hexUtils, StringRevertError } from '@0x/utils';
 | 
				
			||||||
import { LogEntry, LogWithDecodedArgs } from 'ethereum-types';
 | 
					import { LogEntry, LogWithDecodedArgs } from 'ethereum-types';
 | 
				
			||||||
import * as ethjs from 'ethereumjs-util';
 | 
					 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { artifacts } from './artifacts';
 | 
					import { artifacts } from './artifacts';
 | 
				
			||||||
@@ -104,7 +103,7 @@ blockchainTests('Exchange wrapper functions unit tests.', env => {
 | 
				
			|||||||
    // Creates a deterministic order signature, even though no signature validation
 | 
					    // Creates a deterministic order signature, even though no signature validation
 | 
				
			||||||
    // actually occurs in the test contract.
 | 
					    // actually occurs in the test contract.
 | 
				
			||||||
    function createOrderSignature(order: Order): string {
 | 
					    function createOrderSignature(order: Order): string {
 | 
				
			||||||
        return ethjs.bufferToHex(ethjs.sha3(ethjs.toBuffer(orderHashUtils.getOrderHashHex(order))));
 | 
					        return hexUtils.hash(orderHashUtils.getOrderHashHex(order));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Asserts that `_fillOrder()` was called in the same order and with the same
 | 
					    // Asserts that `_fillOrder()` was called in the same order and with the same
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "6.2.24",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "6.2.23",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "6.2.22",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "6.2.21",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "6.2.20",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "6.2.19",
 | 
					        "version": "6.2.19",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v6.2.24 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v6.2.23 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v6.2.22 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v6.2.21 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v6.2.20 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v6.2.19 - _February 10, 2021_
 | 
					## v6.2.19 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-extensions",
 | 
					    "name": "@0x/contracts-extensions",
 | 
				
			||||||
    "version": "6.2.19",
 | 
					    "version": "6.2.24",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -52,23 +52,23 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-asset-proxy": "^3.7.6",
 | 
					        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
				
			||||||
        "@0x/contracts-dev-utils": "^1.3.23",
 | 
					        "@0x/contracts-dev-utils": "^1.3.28",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-erc721": "^3.1.24",
 | 
					        "@0x/contracts-erc721": "^3.1.29",
 | 
				
			||||||
        "@0x/contracts-exchange": "^3.2.25",
 | 
					        "@0x/contracts-exchange": "^3.2.30",
 | 
				
			||||||
        "@0x/contracts-exchange-libs": "^4.3.24",
 | 
					        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -77,7 +77,7 @@
 | 
				
			|||||||
        "chai-bignumber": "^3.0.0",
 | 
					        "chai-bignumber": "^3.0.0",
 | 
				
			||||||
        "dirty-chai": "^2.0.1",
 | 
					        "dirty-chai": "^2.0.1",
 | 
				
			||||||
        "ethereumjs-abi": "0.6.5",
 | 
					        "ethereumjs-abi": "0.6.5",
 | 
				
			||||||
        "ethereumjs-util": "^5.1.1",
 | 
					        "ethereumjs-util": "^7.0.10",
 | 
				
			||||||
        "lodash": "^4.17.11",
 | 
					        "lodash": "^4.17.11",
 | 
				
			||||||
        "make-promises-safe": "^1.1.0",
 | 
					        "make-promises-safe": "^1.1.0",
 | 
				
			||||||
        "mocha": "^6.2.0",
 | 
					        "mocha": "^6.2.0",
 | 
				
			||||||
@@ -87,13 +87,13 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "ethereum-types": "^3.4.0"
 | 
					        "ethereum-types": "^3.5.0"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
        "access": "public"
 | 
					        "access": "public"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-integrations",
 | 
					    "name": "@0x/contracts-integrations",
 | 
				
			||||||
    "version": "2.7.26",
 | 
					    "version": "2.7.40",
 | 
				
			||||||
    "private": true,
 | 
					    "private": true,
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
@@ -52,25 +52,25 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contract-addresses": "^5.10.0",
 | 
					        "@0x/contract-addresses": "^6.1.0",
 | 
				
			||||||
        "@0x/contract-wrappers": "^13.12.3",
 | 
					        "@0x/contract-wrappers": "^13.16.1",
 | 
				
			||||||
        "@0x/contracts-broker": "^1.1.24",
 | 
					        "@0x/contracts-broker": "^1.1.29",
 | 
				
			||||||
        "@0x/contracts-coordinator": "^3.1.25",
 | 
					        "@0x/contracts-coordinator": "^3.1.30",
 | 
				
			||||||
        "@0x/contracts-dev-utils": "^1.3.23",
 | 
					        "@0x/contracts-dev-utils": "^1.3.28",
 | 
				
			||||||
        "@0x/contracts-exchange-forwarder": "^4.2.25",
 | 
					        "@0x/contracts-exchange-forwarder": "^4.2.30",
 | 
				
			||||||
        "@0x/contracts-exchange-libs": "^4.3.24",
 | 
					        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
				
			||||||
        "@0x/contracts-extensions": "^6.2.19",
 | 
					        "@0x/contracts-extensions": "^6.2.24",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/coordinator-server": "^1.0.5",
 | 
					        "@0x/coordinator-server": "^1.0.5",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/migrations": "^6.6.0",
 | 
					        "@0x/migrations": "^8.0.6",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/protocol-utils": "^1.2.0",
 | 
					        "@0x/protocol-utils": "^1.6.0",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@azure/core-asynciterator-polyfill": "^1.0.0",
 | 
					        "@azure/core-asynciterator-polyfill": "^1.0.0",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
@@ -90,26 +90,26 @@
 | 
				
			|||||||
        "solhint": "^1.4.1",
 | 
					        "solhint": "^1.4.1",
 | 
				
			||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/asset-swapper": "^6.0.0",
 | 
					        "@0x/asset-swapper": "^6.10.0",
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/contracts-asset-proxy": "^3.7.6",
 | 
					        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
				
			||||||
        "@0x/contracts-erc1155": "^2.1.24",
 | 
					        "@0x/contracts-erc1155": "^2.1.29",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-erc721": "^3.1.24",
 | 
					        "@0x/contracts-erc721": "^3.1.29",
 | 
				
			||||||
        "@0x/contracts-exchange": "^3.2.25",
 | 
					        "@0x/contracts-exchange": "^3.2.30",
 | 
				
			||||||
        "@0x/contracts-multisig": "^4.1.25",
 | 
					        "@0x/contracts-multisig": "^4.1.30",
 | 
				
			||||||
        "@0x/contracts-staking": "^2.0.32",
 | 
					        "@0x/contracts-staking": "^2.0.37",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/contracts-zero-ex": "^0.18.2",
 | 
					        "@0x/contracts-zero-ex": "^0.23.0",
 | 
				
			||||||
        "@0x/subproviders": "^6.4.1",
 | 
					        "@0x/subproviders": "^6.5.3",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "ethereumjs-util": "^6.2.0",
 | 
					        "ethereumjs-util": "^7.0.10",
 | 
				
			||||||
        "lodash": "^4.17.11"
 | 
					        "lodash": "^4.17.11"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,11 +63,9 @@ blockchainTests.fork('DevUtils dydx order validation tests', env => {
 | 
				
			|||||||
    let dai: ERC20TokenContract;
 | 
					    let dai: ERC20TokenContract;
 | 
				
			||||||
    let usdc: ERC20TokenContract;
 | 
					    let usdc: ERC20TokenContract;
 | 
				
			||||||
    let devUtils: DevUtilsContract;
 | 
					    let devUtils: DevUtilsContract;
 | 
				
			||||||
    let accountOwner: string;
 | 
					 | 
				
			||||||
    let minMarginRatio: number;
 | 
					    let minMarginRatio: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    before(async () => {
 | 
					    before(async () => {
 | 
				
			||||||
        [accountOwner] = await env.getAccountAddressesAsync();
 | 
					 | 
				
			||||||
        dydx = new IDydxContract(DYDX_ADDRESS, env.provider, env.txDefaults);
 | 
					        dydx = new IDydxContract(DYDX_ADDRESS, env.provider, env.txDefaults);
 | 
				
			||||||
        dai = new ERC20TokenContract(DAI_ADDRESS, env.provider, env.txDefaults);
 | 
					        dai = new ERC20TokenContract(DAI_ADDRESS, env.provider, env.txDefaults);
 | 
				
			||||||
        usdc = new ERC20TokenContract(USDC_ADDRESS, env.provider, env.txDefaults);
 | 
					        usdc = new ERC20TokenContract(USDC_ADDRESS, env.provider, env.txDefaults);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,5 +19,5 @@ export function filterActorsByRole<TClass extends Constructor>(
 | 
				
			|||||||
    actors: Actor[],
 | 
					    actors: Actor[],
 | 
				
			||||||
    role: TClass,
 | 
					    role: TClass,
 | 
				
			||||||
): Array<InstanceType<typeof role>> {
 | 
					): Array<InstanceType<typeof role>> {
 | 
				
			||||||
    return actors.filter(actor => actor.mixins.includes(role.name)) as InstanceType<typeof role>;
 | 
					    return actors.filter(actor => actor.mixins.includes(role.name)) as Array<InstanceType<typeof role>>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "4.1.30",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "4.1.29",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "4.1.28",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "4.1.27",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "4.1.26",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "4.1.25",
 | 
					        "version": "4.1.25",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.1.30 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.1.29 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.1.28 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.1.27 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.1.26 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v4.1.25 - _February 10, 2021_
 | 
					## v4.1.25 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-multisig",
 | 
					    "name": "@0x/contracts-multisig",
 | 
				
			||||||
    "version": "4.1.25",
 | 
					    "version": "4.1.30",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -49,18 +49,18 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-asset-proxy": "^3.7.6",
 | 
					        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
@@ -75,12 +75,12 @@
 | 
				
			|||||||
        "shx": "^0.2.2",
 | 
					        "shx": "^0.2.2",
 | 
				
			||||||
        "solhint": "^1.4.1",
 | 
					        "solhint": "^1.4.1",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "ethereum-types": "^3.4.0"
 | 
					        "ethereum-types": "^3.5.0"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
        "access": "public"
 | 
					        "access": "public"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,50 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "version": "2.0.37",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Patch epoch finalization issue",
 | 
				
			||||||
 | 
					                "pr": 221
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "timestamp": 1620214333
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "2.0.36",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "2.0.35",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "2.0.34",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "2.0.33",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "2.0.32",
 | 
					        "version": "2.0.32",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v2.0.37 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Patch epoch finalization issue (#221)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v2.0.36 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v2.0.35 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v2.0.34 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v2.0.33 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v2.0.32 - _February 10, 2021_
 | 
					## v2.0.32 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										55
									
								
								contracts/staking/contracts/src/StakingPatch.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								contracts/staking/contracts/src/StakingPatch.sol
									
									
									
									
									
										Normal 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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -53,6 +53,10 @@ contract MixinExchangeFees is
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        _assertValidProtocolFee(protocolFee);
 | 
					        _assertValidProtocolFee(protocolFee);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (protocolFee == 0) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Transfer the protocol fee to this address if it should be paid in
 | 
					        // Transfer the protocol fee to this address if it should be paid in
 | 
				
			||||||
        // WETH.
 | 
					        // WETH.
 | 
				
			||||||
        if (msg.value == 0) {
 | 
					        if (msg.value == 0) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-staking",
 | 
					    "name": "@0x/contracts-staking",
 | 
				
			||||||
    "version": "2.0.32",
 | 
					    "version": "2.0.37",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -41,7 +41,7 @@
 | 
				
			|||||||
    "config": {
 | 
					    "config": {
 | 
				
			||||||
        "publicInterfaceContracts": "IStaking,IStakingEvents,IStakingProxy,IZrxVault,LibStakingRichErrors,Staking,StakingProxy,ZrxVault,TestStaking",
 | 
					        "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: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": {
 | 
					    "repository": {
 | 
				
			||||||
        "type": "git",
 | 
					        "type": "git",
 | 
				
			||||||
@@ -53,20 +53,20 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-asset-proxy": "^3.7.6",
 | 
					        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
				
			||||||
        "@0x/contracts-dev-utils": "^1.3.23",
 | 
					        "@0x/contracts-dev-utils": "^1.3.28",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-exchange-libs": "^4.3.24",
 | 
					        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-utils": "^4.7.3",
 | 
					        "@0x/contracts-utils": "^4.7.8",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/node": "12.12.54",
 | 
					        "@types/node": "12.12.54",
 | 
				
			||||||
        "chai": "^4.0.1",
 | 
					        "chai": "^4.0.1",
 | 
				
			||||||
@@ -84,15 +84,15 @@
 | 
				
			|||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "ethereumjs-util": "^5.1.1"
 | 
					        "ethereumjs-util": "^7.0.10"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
        "access": "public"
 | 
					        "access": "public"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import { DecodedLogArgs, LogWithDecodedArgs } from 'ethereum-types';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { constants as stakingConstants } from './constants';
 | 
					import { constants as stakingConstants } from './constants';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { Numberish } from '@0x/contracts-test-utils';
 | 
				
			||||||
// tslint:disable:max-classes-per-file
 | 
					// tslint:disable:max-classes-per-file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface StakingParams {
 | 
					export interface StakingParams {
 | 
				
			||||||
@@ -259,5 +260,3 @@ export class AggregatedStats {
 | 
				
			|||||||
export interface AggregatedStatsByEpoch {
 | 
					export interface AggregatedStatsByEpoch {
 | 
				
			||||||
    [epoch: string]: AggregatedStats;
 | 
					    [epoch: string]: AggregatedStats;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
export type Numberish = Numberish;
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,7 @@ import * as MixinStakingPool from '../test/generated-artifacts/MixinStakingPool.
 | 
				
			|||||||
import * as MixinStakingPoolRewards from '../test/generated-artifacts/MixinStakingPoolRewards.json';
 | 
					import * as MixinStakingPoolRewards from '../test/generated-artifacts/MixinStakingPoolRewards.json';
 | 
				
			||||||
import * as MixinStorage from '../test/generated-artifacts/MixinStorage.json';
 | 
					import * as MixinStorage from '../test/generated-artifacts/MixinStorage.json';
 | 
				
			||||||
import * as Staking from '../test/generated-artifacts/Staking.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 StakingProxy from '../test/generated-artifacts/StakingProxy.json';
 | 
				
			||||||
import * as TestAssertStorageParams from '../test/generated-artifacts/TestAssertStorageParams.json';
 | 
					import * as TestAssertStorageParams from '../test/generated-artifacts/TestAssertStorageParams.json';
 | 
				
			||||||
import * as TestCobbDouglas from '../test/generated-artifacts/TestCobbDouglas.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';
 | 
					import * as ZrxVault from '../test/generated-artifacts/ZrxVault.json';
 | 
				
			||||||
export const artifacts = {
 | 
					export const artifacts = {
 | 
				
			||||||
    Staking: Staking as ContractArtifact,
 | 
					    Staking: Staking as ContractArtifact,
 | 
				
			||||||
 | 
					    StakingPatch: StakingPatch as ContractArtifact,
 | 
				
			||||||
    StakingProxy: StakingProxy as ContractArtifact,
 | 
					    StakingProxy: StakingProxy as ContractArtifact,
 | 
				
			||||||
    ZrxVault: ZrxVault as ContractArtifact,
 | 
					    ZrxVault: ZrxVault as ContractArtifact,
 | 
				
			||||||
    MixinExchangeFees: MixinExchangeFees as ContractArtifact,
 | 
					    MixinExchangeFees: MixinExchangeFees as ContractArtifact,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										66
									
								
								contracts/staking/test/patch_mainnet_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								contracts/staking/test/patch_mainnet_test.ts
									
									
									
									
									
										Normal 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
 | 
				
			||||||
@@ -12,7 +12,6 @@ import {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
blockchainTests.resets('Exchange Unit Tests', env => {
 | 
					blockchainTests.resets('Exchange Unit Tests', env => {
 | 
				
			||||||
    // Addresses
 | 
					    // Addresses
 | 
				
			||||||
    let nonOwner: string;
 | 
					 | 
				
			||||||
    let owner: string;
 | 
					    let owner: string;
 | 
				
			||||||
    let nonExchange: string;
 | 
					    let nonExchange: string;
 | 
				
			||||||
    let exchange: string;
 | 
					    let exchange: string;
 | 
				
			||||||
@@ -24,7 +23,7 @@ blockchainTests.resets('Exchange Unit Tests', env => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    before(async () => {
 | 
					    before(async () => {
 | 
				
			||||||
        // Set up addresses for testing.
 | 
					        // Set up addresses for testing.
 | 
				
			||||||
        [nonOwner, owner, nonExchange, exchange, nonAuthority, authority] = await env.getAccountAddressesAsync();
 | 
					        [, owner, nonExchange, exchange, nonAuthority, authority] = await env.getAccountAddressesAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Deploy the Exchange Manager contract.
 | 
					        // Deploy the Exchange Manager contract.
 | 
				
			||||||
        exchangeManager = await TestExchangeManagerContract.deployFrom0xArtifactAsync(
 | 
					        exchangeManager = await TestExchangeManagerContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -543,7 +543,7 @@ blockchainTests.resets('Finalizer unit tests', env => {
 | 
				
			|||||||
            const expectedPoolRewards = await calculatePoolRewardsAsync(INITIAL_BALANCE, pools);
 | 
					            const expectedPoolRewards = await calculatePoolRewardsAsync(INITIAL_BALANCE, pools);
 | 
				
			||||||
            const [pool, reward] = _.sampleSize(shortZip(pools, expectedPoolRewards), 1)[0];
 | 
					            const [pool, reward] = _.sampleSize(shortZip(pools, expectedPoolRewards), 1)[0];
 | 
				
			||||||
            return assertUnfinalizedPoolRewardsAsync(pool.poolId, {
 | 
					            return assertUnfinalizedPoolRewardsAsync(pool.poolId, {
 | 
				
			||||||
                totalReward: (reward as any) as BigNumber,
 | 
					                totalReward: reward,
 | 
				
			||||||
                membersStake: pool.membersStake,
 | 
					                membersStake: pool.membersStake,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,17 +12,13 @@ import * as _ from 'lodash';
 | 
				
			|||||||
import { artifacts } from '../artifacts';
 | 
					import { artifacts } from '../artifacts';
 | 
				
			||||||
import { TestCobbDouglasContract } from '../wrappers';
 | 
					import { TestCobbDouglasContract } from '../wrappers';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// tslint:disable: no-unnecessary-type-assertion
 | 
					 | 
				
			||||||
blockchainTests('LibCobbDouglas unit tests', env => {
 | 
					blockchainTests('LibCobbDouglas unit tests', env => {
 | 
				
			||||||
    const FUZZ_COUNT = 1024;
 | 
					    const FUZZ_COUNT = 1024;
 | 
				
			||||||
    const PRECISION = 15;
 | 
					    const PRECISION = 15;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let testContract: TestCobbDouglasContract;
 | 
					    let testContract: TestCobbDouglasContract;
 | 
				
			||||||
    let ownerAddress: string;
 | 
					 | 
				
			||||||
    let notOwnerAddress: string;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    before(async () => {
 | 
					    before(async () => {
 | 
				
			||||||
        [ownerAddress, notOwnerAddress] = await env.getAccountAddressesAsync();
 | 
					 | 
				
			||||||
        testContract = await TestCobbDouglasContract.deployFrom0xArtifactAsync(
 | 
					        testContract = await TestCobbDouglasContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
            artifacts.TestCobbDouglas,
 | 
					            artifacts.TestCobbDouglas,
 | 
				
			||||||
            env.provider,
 | 
					            env.provider,
 | 
				
			||||||
@@ -211,4 +207,3 @@ blockchainTests('LibCobbDouglas unit tests', env => {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
// tslint:enable:no-unnecessary-type-assertion
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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_staking_pool_rewards';
 | 
				
			||||||
export * from '../test/generated-wrappers/mixin_storage';
 | 
					export * from '../test/generated-wrappers/mixin_storage';
 | 
				
			||||||
export * from '../test/generated-wrappers/staking';
 | 
					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/staking_proxy';
 | 
				
			||||||
export * from '../test/generated-wrappers/test_assert_storage_params';
 | 
					export * from '../test/generated-wrappers/test_assert_storage_params';
 | 
				
			||||||
export * from '../test/generated-wrappers/test_cobb_douglas';
 | 
					export * from '../test/generated-wrappers/test_cobb_douglas';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,7 @@
 | 
				
			|||||||
        "test/generated-artifacts/MixinStakingPoolRewards.json",
 | 
					        "test/generated-artifacts/MixinStakingPoolRewards.json",
 | 
				
			||||||
        "test/generated-artifacts/MixinStorage.json",
 | 
					        "test/generated-artifacts/MixinStorage.json",
 | 
				
			||||||
        "test/generated-artifacts/Staking.json",
 | 
					        "test/generated-artifacts/Staking.json",
 | 
				
			||||||
 | 
					        "test/generated-artifacts/StakingPatch.json",
 | 
				
			||||||
        "test/generated-artifacts/StakingProxy.json",
 | 
					        "test/generated-artifacts/StakingProxy.json",
 | 
				
			||||||
        "test/generated-artifacts/TestAssertStorageParams.json",
 | 
					        "test/generated-artifacts/TestAssertStorageParams.json",
 | 
				
			||||||
        "test/generated-artifacts/TestCobbDouglas.json",
 | 
					        "test/generated-artifacts/TestCobbDouglas.json",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,50 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "version": "5.4.0",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Set default ganache gas limit to 100e6",
 | 
				
			||||||
 | 
					                "pr": 197
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "timestamp": 1620214333
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "5.3.25",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "5.3.24",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "5.3.23",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "5.3.22",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "5.3.21",
 | 
					        "version": "5.3.21",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v5.4.0 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Set default ganache gas limit to 100e6 (#197)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v5.3.25 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v5.3.24 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v5.3.23 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v5.3.22 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v5.3.21 - _February 10, 2021_
 | 
					## v5.3.21 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-test-utils",
 | 
					    "name": "@0x/contracts-test-utils",
 | 
				
			||||||
    "version": "5.3.21",
 | 
					    "version": "5.4.0",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -34,28 +34,28 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "npm-run-all": "^4.1.2",
 | 
					        "npm-run-all": "^4.1.2",
 | 
				
			||||||
        "shx": "^0.2.2",
 | 
					        "shx": "^0.2.2",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/assert": "^3.0.21",
 | 
					        "@0x/assert": "^3.0.27",
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/contract-addresses": "^5.10.0",
 | 
					        "@0x/contract-addresses": "^6.1.0",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/json-schemas": "^5.4.1",
 | 
					        "@0x/json-schemas": "^6.1.3",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/sol-coverage": "^4.0.29",
 | 
					        "@0x/sol-coverage": "^4.0.37",
 | 
				
			||||||
        "@0x/sol-profiler": "^4.1.19",
 | 
					        "@0x/sol-profiler": "^4.1.27",
 | 
				
			||||||
        "@0x/sol-trace": "^3.0.29",
 | 
					        "@0x/sol-trace": "^3.0.37",
 | 
				
			||||||
        "@0x/subproviders": "^6.4.1",
 | 
					        "@0x/subproviders": "^6.5.3",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/bn.js": "^4.11.0",
 | 
					        "@types/bn.js": "^4.11.0",
 | 
				
			||||||
        "@types/js-combinatorics": "^0.5.29",
 | 
					        "@types/js-combinatorics": "^0.5.29",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
@@ -67,8 +67,8 @@
 | 
				
			|||||||
        "chai-bignumber": "^3.0.0",
 | 
					        "chai-bignumber": "^3.0.0",
 | 
				
			||||||
        "decimal.js": "^10.2.0",
 | 
					        "decimal.js": "^10.2.0",
 | 
				
			||||||
        "dirty-chai": "^2.0.1",
 | 
					        "dirty-chai": "^2.0.1",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "ethereumjs-util": "^5.1.1",
 | 
					        "ethereumjs-util": "^7.0.10",
 | 
				
			||||||
        "ethers": "~4.0.4",
 | 
					        "ethers": "~4.0.4",
 | 
				
			||||||
        "js-combinatorics": "^0.5.3",
 | 
					        "js-combinatorics": "^0.5.3",
 | 
				
			||||||
        "lodash": "^4.17.11",
 | 
					        "lodash": "^4.17.11",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,7 +77,7 @@ export const constants = {
 | 
				
			|||||||
    ZERO_AMOUNT: new BigNumber(0),
 | 
					    ZERO_AMOUNT: new BigNumber(0),
 | 
				
			||||||
    PERCENTAGE_DENOMINATOR: new BigNumber(10).pow(18),
 | 
					    PERCENTAGE_DENOMINATOR: new BigNumber(10).pow(18),
 | 
				
			||||||
    TIME_BUFFER: new BigNumber(1000),
 | 
					    TIME_BUFFER: new BigNumber(1000),
 | 
				
			||||||
    KECCAK256_NULL: ethUtil.addHexPrefix(ethUtil.bufferToHex(ethUtil.SHA3_NULL)),
 | 
					    KECCAK256_NULL: ethUtil.bufferToHex(ethUtil.keccak256(Buffer.alloc(0))),
 | 
				
			||||||
    MAX_UINT256_ROOT: new BigNumber('340282366920938463463374607431768211456'),
 | 
					    MAX_UINT256_ROOT: new BigNumber('340282366920938463463374607431768211456'),
 | 
				
			||||||
    ONE_ETHER: new BigNumber(1e18),
 | 
					    ONE_ETHER: new BigNumber(1e18),
 | 
				
			||||||
    EIP712_DOMAIN_NAME: '0x Protocol',
 | 
					    EIP712_DOMAIN_NAME: '0x Protocol',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ export function shortZip<T1, T2>(a: T1[], b: T2[]): Array<[T1, T2]> {
 | 
				
			|||||||
export function replaceKeysDeep(obj: {}, mapKeys: (key: string) => string | void): _.Dictionary<{}> {
 | 
					export function replaceKeysDeep(obj: {}, mapKeys: (key: string) => string | void): _.Dictionary<{}> {
 | 
				
			||||||
    return _.transform(obj, (result, value, key) => {
 | 
					    return _.transform(obj, (result, value, key) => {
 | 
				
			||||||
        const currentKey = mapKeys(key) || key;
 | 
					        const currentKey = mapKeys(key) || key;
 | 
				
			||||||
        result[currentKey] = _.isObject(value) ? replaceKeysDeep(value, mapKeys) : value;
 | 
					        result[currentKey] = _.isObject(value) ? replaceKeysDeep(value as {}, mapKeys) : (value as {});
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,14 +22,14 @@ export class OrderFactory {
 | 
				
			|||||||
    ): Promise<SignedOrder> {
 | 
					    ): Promise<SignedOrder> {
 | 
				
			||||||
        const fifteenMinutesInSeconds = 15 * 60;
 | 
					        const fifteenMinutesInSeconds = 15 * 60;
 | 
				
			||||||
        const currentBlockTimestamp = await getLatestBlockTimestampAsync();
 | 
					        const currentBlockTimestamp = await getLatestBlockTimestampAsync();
 | 
				
			||||||
        const order = ({
 | 
					        const order = {
 | 
				
			||||||
            takerAddress: constants.NULL_ADDRESS,
 | 
					            takerAddress: constants.NULL_ADDRESS,
 | 
				
			||||||
            senderAddress: constants.NULL_ADDRESS,
 | 
					            senderAddress: constants.NULL_ADDRESS,
 | 
				
			||||||
            expirationTimeSeconds: new BigNumber(currentBlockTimestamp).plus(fifteenMinutesInSeconds),
 | 
					            expirationTimeSeconds: new BigNumber(currentBlockTimestamp).plus(fifteenMinutesInSeconds),
 | 
				
			||||||
            salt: generatePseudoRandomSalt(),
 | 
					            salt: generatePseudoRandomSalt(),
 | 
				
			||||||
            ...this._defaultOrderParams,
 | 
					            ...this._defaultOrderParams,
 | 
				
			||||||
            ...customOrderParams,
 | 
					            ...customOrderParams,
 | 
				
			||||||
        } as any) as Order;
 | 
					        } as Order; // tslint:disable-line:no-object-literal-type-assertion
 | 
				
			||||||
        const orderHashBuff = orderHashUtils.getOrderHashBuffer(order);
 | 
					        const orderHashBuff = orderHashUtils.getOrderHashBuffer(order);
 | 
				
			||||||
        const signature = signingUtils.signMessage(orderHashBuff, this._privateKey, signatureType);
 | 
					        const signature = signingUtils.signMessage(orderHashBuff, this._privateKey, signatureType);
 | 
				
			||||||
        const signedOrder = {
 | 
					        const signedOrder = {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,8 @@ export const orderUtils = {
 | 
				
			|||||||
        return cancel;
 | 
					        return cancel;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    createOrderWithoutSignature(signedOrder: SignedOrder): Order {
 | 
					    createOrderWithoutSignature(signedOrder: SignedOrder): Order {
 | 
				
			||||||
        return _.omit(signedOrder, ['signature']) as Order;
 | 
					        const { signature, ...order } = signedOrder;
 | 
				
			||||||
 | 
					        return order;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    createBatchMatchOrders(signedOrdersLeft: SignedOrder[], signedOrdersRight: SignedOrder[]): BatchMatchOrder {
 | 
					    createBatchMatchOrders(signedOrdersLeft: SignedOrder[], signedOrdersRight: SignedOrder[]): BatchMatchOrder {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ export let providerConfigs: Web3Config = {
 | 
				
			|||||||
    shouldUseInProcessGanache: true,
 | 
					    shouldUseInProcessGanache: true,
 | 
				
			||||||
    shouldAllowUnlimitedContractSize: true,
 | 
					    shouldAllowUnlimitedContractSize: true,
 | 
				
			||||||
    hardfork: 'istanbul',
 | 
					    hardfork: 'istanbul',
 | 
				
			||||||
 | 
					    gasLimit: 100e6,
 | 
				
			||||||
    unlocked_accounts: [
 | 
					    unlocked_accounts: [
 | 
				
			||||||
        '0x6cc5f688a315f3dc28a7781717a9a798a59fda7b',
 | 
					        '0x6cc5f688a315f3dc28a7781717a9a798a59fda7b',
 | 
				
			||||||
        '0x55dc8f21d20d4c6ed3c82916a438a413ca68e335',
 | 
					        '0x55dc8f21d20d4c6ed3c82916a438a413ca68e335',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,9 +57,7 @@ describe('Order hashing', () => {
 | 
				
			|||||||
                ...order,
 | 
					                ...order,
 | 
				
			||||||
                takerAddress: (null as any) as string,
 | 
					                takerAddress: (null as any) as string,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            const expectedErrorMessage = `Order taker must be of type string. If you want anyone to be able to fill an order - pass ${
 | 
					            const expectedErrorMessage = `Expected order to conform to schema`;
 | 
				
			||||||
                constants.NULL_ADDRESS
 | 
					 | 
				
			||||||
            }`;
 | 
					 | 
				
			||||||
            expect(() => orderHashUtils.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
 | 
					            expect(() => orderHashUtils.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,78 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "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",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619481586,
 | 
				
			||||||
 | 
					        "version": "1.1.3",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1618259868,
 | 
				
			||||||
 | 
					        "version": "1.1.2",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "1.1.1",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "version": "1.1.0",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Make the proposal/quorum thresholds updatable",
 | 
				
			||||||
 | 
					                "pr": 165
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "timestamp": 1616005394
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "1.0.2",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "1.0.1",
 | 
					        "version": "1.0.1",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,38 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.1.3 - _April 26, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.1.2 - _April 12, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.1.1 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.1.0 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Make the proposal/quorum thresholds updatable (#165)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.0.2 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v1.0.1 - _February 10, 2021_
 | 
					## v1.0.1 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,6 +30,7 @@ interface IZrxTreasury {
 | 
				
			|||||||
        uint256 votingPeriod;
 | 
					        uint256 votingPeriod;
 | 
				
			||||||
        uint256 proposalThreshold;
 | 
					        uint256 proposalThreshold;
 | 
				
			||||||
        uint256 quorumThreshold;
 | 
					        uint256 quorumThreshold;
 | 
				
			||||||
 | 
					        bytes32 defaultPoolId;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct ProposedAction {
 | 
					    struct ProposedAction {
 | 
				
			||||||
@@ -96,6 +97,18 @@ interface IZrxTreasury {
 | 
				
			|||||||
        view
 | 
					        view
 | 
				
			||||||
        returns (uint256);
 | 
					        returns (uint256);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @dev Updates the proposal and quorum thresholds to the given
 | 
				
			||||||
 | 
					    ///      values. Note that this function is only callable by the
 | 
				
			||||||
 | 
					    ///      treasury contract itself, so the threshold can only be
 | 
				
			||||||
 | 
					    ///      updated via a successful treasury proposal.
 | 
				
			||||||
 | 
					    /// @param newProposalThreshold The new value for the proposal threshold.
 | 
				
			||||||
 | 
					    /// @param newQuorumThreshold The new value for the quorum threshold.
 | 
				
			||||||
 | 
					    function updateThresholds(
 | 
				
			||||||
 | 
					        uint256 newProposalThreshold,
 | 
				
			||||||
 | 
					        uint256 newQuorumThreshold
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        external;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev Creates a proposal to send ZRX from this treasury on the
 | 
					    /// @dev Creates a proposal to send ZRX from this treasury on the
 | 
				
			||||||
    ///      the given actions. Must have at least `proposalThreshold`
 | 
					    ///      the given actions. Must have at least `proposalThreshold`
 | 
				
			||||||
    ///      of voting power to call this function. See `getVotingPower`
 | 
					    ///      of voting power to call this function. See `getVotingPower`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,6 @@
 | 
				
			|||||||
pragma solidity ^0.6.12;
 | 
					pragma solidity ^0.6.12;
 | 
				
			||||||
pragma experimental ABIEncoderV2;
 | 
					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/LibBytesV06.sol";
 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
					import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
					import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
				
			||||||
@@ -32,7 +30,6 @@ import "./IZrxTreasury.sol";
 | 
				
			|||||||
contract ZrxTreasury is
 | 
					contract ZrxTreasury is
 | 
				
			||||||
    IZrxTreasury
 | 
					    IZrxTreasury
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
					 | 
				
			||||||
    using LibSafeMathV06 for uint256;
 | 
					    using LibSafeMathV06 for uint256;
 | 
				
			||||||
    using LibRichErrorsV06 for bytes;
 | 
					    using LibRichErrorsV06 for bytes;
 | 
				
			||||||
    using LibBytesV06 for bytes;
 | 
					    using LibBytesV06 for bytes;
 | 
				
			||||||
@@ -42,8 +39,8 @@ contract ZrxTreasury is
 | 
				
			|||||||
    DefaultPoolOperator public immutable override defaultPoolOperator;
 | 
					    DefaultPoolOperator public immutable override defaultPoolOperator;
 | 
				
			||||||
    bytes32 public immutable override defaultPoolId;
 | 
					    bytes32 public immutable override defaultPoolId;
 | 
				
			||||||
    uint256 public immutable override votingPeriod;
 | 
					    uint256 public immutable override votingPeriod;
 | 
				
			||||||
    uint256 public immutable override proposalThreshold;
 | 
					    uint256 public override proposalThreshold;
 | 
				
			||||||
    uint256 public immutable override quorumThreshold;
 | 
					    uint256 public override quorumThreshold;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Storage
 | 
					    // Storage
 | 
				
			||||||
    Proposal[] public proposals;
 | 
					    Proposal[] public proposals;
 | 
				
			||||||
@@ -52,11 +49,9 @@ contract ZrxTreasury is
 | 
				
			|||||||
    /// @dev Initializes the ZRX treasury and creates the default
 | 
					    /// @dev Initializes the ZRX treasury and creates the default
 | 
				
			||||||
    ///      staking pool.
 | 
					    ///      staking pool.
 | 
				
			||||||
    /// @param stakingProxy_ The 0x staking proxy contract.
 | 
					    /// @param stakingProxy_ The 0x staking proxy contract.
 | 
				
			||||||
    /// @param weth_ The WETH token contract.
 | 
					 | 
				
			||||||
    /// @param params Immutable treasury parameters.
 | 
					    /// @param params Immutable treasury parameters.
 | 
				
			||||||
    constructor(
 | 
					    constructor(
 | 
				
			||||||
        IStaking stakingProxy_,
 | 
					        IStaking stakingProxy_,
 | 
				
			||||||
        IERC20TokenV06 weth_,
 | 
					 | 
				
			||||||
        TreasuryParameters memory params
 | 
					        TreasuryParameters memory params
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
@@ -66,15 +61,12 @@ contract ZrxTreasury is
 | 
				
			|||||||
            "VOTING_PERIOD_TOO_LONG"
 | 
					            "VOTING_PERIOD_TOO_LONG"
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        stakingProxy = stakingProxy_;
 | 
					        stakingProxy = stakingProxy_;
 | 
				
			||||||
        DefaultPoolOperator defaultPoolOperator_ = new DefaultPoolOperator(
 | 
					 | 
				
			||||||
            stakingProxy_,
 | 
					 | 
				
			||||||
            weth_
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        defaultPoolOperator = defaultPoolOperator_;
 | 
					 | 
				
			||||||
        defaultPoolId = defaultPoolOperator_.poolId();
 | 
					 | 
				
			||||||
        votingPeriod = params.votingPeriod;
 | 
					        votingPeriod = params.votingPeriod;
 | 
				
			||||||
        proposalThreshold = params.proposalThreshold;
 | 
					        proposalThreshold = params.proposalThreshold;
 | 
				
			||||||
        quorumThreshold = params.quorumThreshold;
 | 
					        quorumThreshold = params.quorumThreshold;
 | 
				
			||||||
 | 
					        defaultPoolId = params.defaultPoolId;
 | 
				
			||||||
 | 
					        IStaking.Pool memory defaultPool = stakingProxy_.getStakingPool(params.defaultPoolId);
 | 
				
			||||||
 | 
					        defaultPoolOperator = DefaultPoolOperator(defaultPool.operator);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // solhint-disable
 | 
					    // solhint-disable
 | 
				
			||||||
@@ -82,6 +74,24 @@ contract ZrxTreasury is
 | 
				
			|||||||
    receive() external payable {}
 | 
					    receive() external payable {}
 | 
				
			||||||
    // solhint-enable
 | 
					    // solhint-enable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @dev Updates the proposal and quorum thresholds to the given
 | 
				
			||||||
 | 
					    ///      values. Note that this function is only callable by the
 | 
				
			||||||
 | 
					    ///      treasury contract itself, so the threshold can only be
 | 
				
			||||||
 | 
					    ///      updated via a successful treasury proposal.
 | 
				
			||||||
 | 
					    /// @param newProposalThreshold The new value for the proposal threshold.
 | 
				
			||||||
 | 
					    /// @param newQuorumThreshold The new value for the quorum threshold.
 | 
				
			||||||
 | 
					    function updateThresholds(
 | 
				
			||||||
 | 
					        uint256 newProposalThreshold,
 | 
				
			||||||
 | 
					        uint256 newQuorumThreshold
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        external
 | 
				
			||||||
 | 
					        override
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        require(msg.sender == address(this), "updateThresholds/ONLY_SELF");
 | 
				
			||||||
 | 
					        proposalThreshold = newProposalThreshold;
 | 
				
			||||||
 | 
					        quorumThreshold = newQuorumThreshold;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev Creates a proposal to send ZRX from this treasury on the
 | 
					    /// @dev Creates a proposal to send ZRX from this treasury on the
 | 
				
			||||||
    ///      the given actions. Must have at least `proposalThreshold`
 | 
					    ///      the given actions. Must have at least `proposalThreshold`
 | 
				
			||||||
    ///      of voting power to call this function. See `getVotingPower`
 | 
					    ///      of voting power to call this function. See `getVotingPower`
 | 
				
			||||||
@@ -268,6 +278,12 @@ contract ZrxTreasury is
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Add voting power for operated staking pools.
 | 
					        // Add voting power for operated staking pools.
 | 
				
			||||||
        for (uint256 i = 0; i != operatedPoolIds.length; i++) {
 | 
					        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]);
 | 
					            IStaking.Pool memory pool = stakingProxy.getStakingPool(operatedPoolIds[i]);
 | 
				
			||||||
            require(
 | 
					            require(
 | 
				
			||||||
                pool.operator == account,
 | 
					                pool.operator == account,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-treasury",
 | 
					    "name": "@0x/contracts-treasury",
 | 
				
			||||||
    "version": "1.0.1",
 | 
					    "version": "1.1.6",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -46,16 +46,16 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.13",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contract-addresses": "^5.10.0",
 | 
					        "@0x/contract-addresses": "^6.1.0",
 | 
				
			||||||
        "@0x/contracts-asset-proxy": "^3.7.6",
 | 
					        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
				
			||||||
        "@0x/contracts-erc20": "^3.3.3",
 | 
					        "@0x/contracts-erc20": "^3.3.8",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.24",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-staking": "^2.0.32",
 | 
					        "@0x/contracts-staking": "^2.0.37",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.4.1",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
					        "@0x/ts-doc-gen": "^0.0.28",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@types/isomorphic-fetch": "^0.0.35",
 | 
					        "@types/isomorphic-fetch": "^0.0.35",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
@@ -69,18 +69,18 @@
 | 
				
			|||||||
        "solhint": "^1.4.1",
 | 
					        "solhint": "^1.4.1",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typedoc": "~0.16.11",
 | 
					        "typedoc": "~0.16.11",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.14",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/protocol-utils": "^1.2.0",
 | 
					        "@0x/protocol-utils": "^1.6.0",
 | 
				
			||||||
        "@0x/subproviders": "^6.2.3",
 | 
					        "@0x/subproviders": "^6.5.3",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.1.1",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.3.0",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "ethereum-types": "^3.4.0",
 | 
					        "ethereum-types": "^3.5.0",
 | 
				
			||||||
        "ethereumjs-util": "^5.1.1"
 | 
					        "ethereumjs-util": "^7.0.10"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
        "access": "public"
 | 
					        "access": "public"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,7 @@ blockchainTests.resets('Treasury governance', env => {
 | 
				
			|||||||
        votingPeriod: new BigNumber(3).times(stakingConstants.ONE_DAY_IN_SECONDS),
 | 
					        votingPeriod: new BigNumber(3).times(stakingConstants.ONE_DAY_IN_SECONDS),
 | 
				
			||||||
        proposalThreshold: new BigNumber(100),
 | 
					        proposalThreshold: new BigNumber(100),
 | 
				
			||||||
        quorumThreshold: new BigNumber(1000),
 | 
					        quorumThreshold: new BigNumber(1000),
 | 
				
			||||||
 | 
					        defaultPoolId: stakingConstants.INITIAL_POOL_ID,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    const PROPOSAL_DESCRIPTION = 'A very compelling proposal!';
 | 
					    const PROPOSAL_DESCRIPTION = 'A very compelling proposal!';
 | 
				
			||||||
    const TREASURY_BALANCE = constants.INITIAL_ERC20_BALANCE;
 | 
					    const TREASURY_BALANCE = constants.INITIAL_ERC20_BALANCE;
 | 
				
			||||||
@@ -135,6 +136,16 @@ blockchainTests.resets('Treasury governance', env => {
 | 
				
			|||||||
            .approve(erc20ProxyContract.address, constants.INITIAL_ERC20_ALLOWANCE)
 | 
					            .approve(erc20ProxyContract.address, constants.INITIAL_ERC20_ALLOWANCE)
 | 
				
			||||||
            .awaitTransactionSuccessAsync({ from: delegator });
 | 
					            .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);
 | 
					        const createStakingPoolTx = staking.createStakingPool(stakingConstants.PPM, false);
 | 
				
			||||||
        nonDefaultPoolId = await createStakingPoolTx.callAsync({ from: poolOperator });
 | 
					        nonDefaultPoolId = await createStakingPoolTx.callAsync({ from: poolOperator });
 | 
				
			||||||
        await createStakingPoolTx.awaitTransactionSuccessAsync({ from: poolOperator });
 | 
					        await createStakingPoolTx.awaitTransactionSuccessAsync({ from: poolOperator });
 | 
				
			||||||
@@ -145,9 +156,9 @@ blockchainTests.resets('Treasury governance', env => {
 | 
				
			|||||||
            env.txDefaults,
 | 
					            env.txDefaults,
 | 
				
			||||||
            { ...artifacts, ...erc20Artifacts },
 | 
					            { ...artifacts, ...erc20Artifacts },
 | 
				
			||||||
            staking.address,
 | 
					            staking.address,
 | 
				
			||||||
            weth.address,
 | 
					 | 
				
			||||||
            TREASURY_PARAMS,
 | 
					            TREASURY_PARAMS,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await zrx.mint(TREASURY_BALANCE).awaitTransactionSuccessAsync();
 | 
					        await zrx.mint(TREASURY_BALANCE).awaitTransactionSuccessAsync();
 | 
				
			||||||
        await zrx.transfer(treasury.address, TREASURY_BALANCE).awaitTransactionSuccessAsync();
 | 
					        await zrx.transfer(treasury.address, TREASURY_BALANCE).awaitTransactionSuccessAsync();
 | 
				
			||||||
        actions = [
 | 
					        actions = [
 | 
				
			||||||
@@ -166,10 +177,6 @@ blockchainTests.resets('Treasury governance', env => {
 | 
				
			|||||||
                value: constants.ZERO_AMOUNT,
 | 
					                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()', () => {
 | 
					    describe('getVotingPower()', () => {
 | 
				
			||||||
        it('Unstaked ZRX has no voting power', async () => {
 | 
					        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();
 | 
					            const operatorVotingPower = await treasury.getVotingPower(poolOperator, [nonDefaultPoolId]).callAsync();
 | 
				
			||||||
            expect(operatorVotingPower).to.bignumber.equal(TREASURY_PARAMS.proposalThreshold.dividedBy(2));
 | 
					            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 () => {
 | 
					        it('Correctly sums voting power delegated to multiple pools', async () => {
 | 
				
			||||||
            await staking
 | 
					            await staking
 | 
				
			||||||
                .stake(TREASURY_PARAMS.proposalThreshold.times(2))
 | 
					                .stake(TREASURY_PARAMS.proposalThreshold.times(2))
 | 
				
			||||||
@@ -580,4 +600,47 @@ blockchainTests.resets('Treasury governance', env => {
 | 
				
			|||||||
            expect(await weth.balanceOf(staking.address).callAsync()).to.bignumber.equal(wethAmount);
 | 
					            expect(await weth.balanceOf(staking.address).callAsync()).to.bignumber.equal(wethAmount);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    describe('Can update thresholds via proposal', () => {
 | 
				
			||||||
 | 
					        it('Updates proposal and quorum thresholds', async () => {
 | 
				
			||||||
 | 
					            // Delegator has enough ZRX to create and pass a proposal
 | 
				
			||||||
 | 
					            await staking.stake(TREASURY_PARAMS.quorumThreshold).awaitTransactionSuccessAsync({ from: delegator });
 | 
				
			||||||
 | 
					            await staking
 | 
				
			||||||
 | 
					                .moveStake(
 | 
				
			||||||
 | 
					                    new StakeInfo(StakeStatus.Undelegated),
 | 
				
			||||||
 | 
					                    new StakeInfo(StakeStatus.Delegated, defaultPoolId),
 | 
				
			||||||
 | 
					                    TREASURY_PARAMS.quorumThreshold,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                .awaitTransactionSuccessAsync({ from: delegator });
 | 
				
			||||||
 | 
					            await fastForwardToNextEpochAsync();
 | 
				
			||||||
 | 
					            const currentEpoch = await staking.currentEpoch().callAsync();
 | 
				
			||||||
 | 
					            const newProposalThreshold = new BigNumber(420);
 | 
				
			||||||
 | 
					            const newQuorumThreshold = new BigNumber(1337);
 | 
				
			||||||
 | 
					            const updateThresholdsAction = {
 | 
				
			||||||
 | 
					                target: treasury.address,
 | 
				
			||||||
 | 
					                data: treasury
 | 
				
			||||||
 | 
					                    .updateThresholds(newProposalThreshold, newQuorumThreshold)
 | 
				
			||||||
 | 
					                    .getABIEncodedTransactionData(),
 | 
				
			||||||
 | 
					                value: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            const tx = treasury.propose(
 | 
				
			||||||
 | 
					                [updateThresholdsAction],
 | 
				
			||||||
 | 
					                currentEpoch.plus(3),
 | 
				
			||||||
 | 
					                `Updates proposal threshold to ${newProposalThreshold} and quorum threshold to ${newQuorumThreshold}`,
 | 
				
			||||||
 | 
					                [],
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            const proposalId = await tx.callAsync({ from: delegator });
 | 
				
			||||||
 | 
					            await tx.awaitTransactionSuccessAsync({ from: delegator });
 | 
				
			||||||
 | 
					            await fastForwardToNextEpochAsync();
 | 
				
			||||||
 | 
					            await fastForwardToNextEpochAsync();
 | 
				
			||||||
 | 
					            await treasury.castVote(proposalId, true, []).awaitTransactionSuccessAsync({ from: delegator });
 | 
				
			||||||
 | 
					            await fastForwardToNextEpochAsync();
 | 
				
			||||||
 | 
					            await treasury
 | 
				
			||||||
 | 
					                .execute(proposalId, [updateThresholdsAction])
 | 
				
			||||||
 | 
					                .awaitTransactionSuccessAsync({ from: delegator });
 | 
				
			||||||
 | 
					            const proposalThreshold = await treasury.proposalThreshold().callAsync();
 | 
				
			||||||
 | 
					            const quorumThreshold = await treasury.quorumThreshold().callAsync();
 | 
				
			||||||
 | 
					            expect(proposalThreshold).to.bignumber.equal(newProposalThreshold);
 | 
				
			||||||
 | 
					            expect(quorumThreshold).to.bignumber.equal(newQuorumThreshold);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,49 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1620214333,
 | 
				
			||||||
 | 
					        "version": "4.7.8",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1619596077,
 | 
				
			||||||
 | 
					        "version": "4.7.7",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1617311315,
 | 
				
			||||||
 | 
					        "version": "4.7.6",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1616005394,
 | 
				
			||||||
 | 
					        "version": "4.7.5",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1614141718,
 | 
				
			||||||
 | 
					        "version": "4.7.4",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "timestamp": 1612950500,
 | 
					        "timestamp": 1612950500,
 | 
				
			||||||
        "version": "4.7.3",
 | 
					        "version": "4.7.3",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.7.8 - _May 5, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.7.7 - _April 28, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.7.6 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.7.5 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v4.7.4 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v4.7.3 - _February 10, 2021_
 | 
					## v4.7.3 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Dependencies updated
 | 
					    * Dependencies updated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "@0x/contracts-utils",
 | 
					    "name": "@0x/contracts-utils",
 | 
				
			||||||
    "version": "4.7.3",
 | 
					    "version": "4.7.8",
 | 
				
			||||||
    "engines": {
 | 
					    "engines": {
 | 
				
			||||||
        "node": ">=6.12"
 | 
					        "node": ">=6.12"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -50,15 +50,15 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils",
 | 
					    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils",
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
        "@0x/abi-gen": "^5.4.19",
 | 
					        "@0x/abi-gen": "^5.6.0",
 | 
				
			||||||
        "@0x/contracts-gen": "^2.0.30",
 | 
					        "@0x/contracts-gen": "^2.0.38",
 | 
				
			||||||
        "@0x/contracts-test-utils": "^5.3.21",
 | 
					        "@0x/contracts-test-utils": "^5.4.0",
 | 
				
			||||||
        "@0x/dev-utils": "^4.2.1",
 | 
					        "@0x/dev-utils": "^4.2.7",
 | 
				
			||||||
        "@0x/order-utils": "^10.4.16",
 | 
					        "@0x/order-utils": "^10.4.21",
 | 
				
			||||||
        "@0x/sol-compiler": "^4.5.2",
 | 
					        "@0x/sol-compiler": "^4.7.3",
 | 
				
			||||||
        "@0x/tslint-config": "^4.1.3",
 | 
					        "@0x/tslint-config": "^4.1.4",
 | 
				
			||||||
        "@0x/types": "^3.3.1",
 | 
					        "@0x/types": "^3.3.3",
 | 
				
			||||||
        "@0x/web3-wrapper": "^7.4.1",
 | 
					        "@0x/web3-wrapper": "^7.5.3",
 | 
				
			||||||
        "@types/bn.js": "^4.11.0",
 | 
					        "@types/bn.js": "^4.11.0",
 | 
				
			||||||
        "@types/lodash": "4.14.104",
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
        "@types/mocha": "^5.2.7",
 | 
					        "@types/mocha": "^5.2.7",
 | 
				
			||||||
@@ -67,7 +67,7 @@
 | 
				
			|||||||
        "chai-as-promised": "^7.1.0",
 | 
					        "chai-as-promised": "^7.1.0",
 | 
				
			||||||
        "chai-bignumber": "^3.0.0",
 | 
					        "chai-bignumber": "^3.0.0",
 | 
				
			||||||
        "dirty-chai": "^2.0.1",
 | 
					        "dirty-chai": "^2.0.1",
 | 
				
			||||||
        "ethereumjs-util": "^5.1.1",
 | 
					        "ethereumjs-util": "^7.0.10",
 | 
				
			||||||
        "lodash": "^4.17.11",
 | 
					        "lodash": "^4.17.11",
 | 
				
			||||||
        "make-promises-safe": "^1.1.0",
 | 
					        "make-promises-safe": "^1.1.0",
 | 
				
			||||||
        "mocha": "^6.2.0",
 | 
					        "mocha": "^6.2.0",
 | 
				
			||||||
@@ -76,14 +76,14 @@
 | 
				
			|||||||
        "solhint": "^1.4.1",
 | 
					        "solhint": "^1.4.1",
 | 
				
			||||||
        "truffle": "^5.0.32",
 | 
					        "truffle": "^5.0.32",
 | 
				
			||||||
        "tslint": "5.11.0",
 | 
					        "tslint": "5.11.0",
 | 
				
			||||||
        "typescript": "3.0.1"
 | 
					        "typescript": "4.2.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.18",
 | 
					        "@0x/base-contract": "^6.4.0",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.6",
 | 
					        "@0x/typescript-typings": "^5.2.0",
 | 
				
			||||||
        "@0x/utils": "^6.2.0",
 | 
					        "@0x/utils": "^6.4.3",
 | 
				
			||||||
        "bn.js": "^4.11.8",
 | 
					        "bn.js": "^4.11.8",
 | 
				
			||||||
        "ethereum-types": "^3.4.0"
 | 
					        "ethereum-types": "^3.5.0"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "publishConfig": {
 | 
					    "publishConfig": {
 | 
				
			||||||
        "access": "public"
 | 
					        "access": "public"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@ import { chaiSetup, constants, provider, txDefaults, web3Wrapper } from '@0x/con
 | 
				
			|||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
 | 
					import { BlockchainLifecycle } from '@0x/dev-utils';
 | 
				
			||||||
import { BigNumber, hexUtils, signTypedDataUtils } from '@0x/utils';
 | 
					import { BigNumber, hexUtils, signTypedDataUtils } from '@0x/utils';
 | 
				
			||||||
import * as chai from 'chai';
 | 
					import * as chai from 'chai';
 | 
				
			||||||
import * as ethUtil from 'ethereumjs-util';
 | 
					 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { artifacts } from './artifacts';
 | 
					import { artifacts } from './artifacts';
 | 
				
			||||||
@@ -78,7 +77,7 @@ describe('LibEIP712', () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Hash the provided input to get the expected hash
 | 
					        // Hash the provided input to get the expected hash
 | 
				
			||||||
        const input = '0x1901'.concat(unprefixedDomainHash.concat(unprefixedHashStruct));
 | 
					        const input = '0x1901'.concat(unprefixedDomainHash.concat(unprefixedHashStruct));
 | 
				
			||||||
        const expectedHash = '0x'.concat(ethUtil.sha3(input).toString('hex'));
 | 
					        const expectedHash = hexUtils.hash(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Get the actual hash by calling the smart contract
 | 
					        // Get the actual hash by calling the smart contract
 | 
				
			||||||
        const actualHash = await lib.externalHashEIP712Message(domainHash, hashStruct).callAsync();
 | 
					        const actualHash = await lib.externalHashEIP712Message(domainHash, hashStruct).callAsync();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,151 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "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": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "bump feature version to 1.2",
 | 
				
			||||||
 | 
					                "pr": 213
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "timestamp": 1619596077
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "version": "0.22.0",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Add order signer registry to NativeOrdersFeature",
 | 
				
			||||||
 | 
					                "pr": 195
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "timestamp": 1619481586
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "timestamp": 1618259868,
 | 
				
			||||||
 | 
					        "version": "0.21.1",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Dependencies updated"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap)",
 | 
				
			||||||
 | 
					                "pr": 208
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "version": "0.21.0",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Encoding protocol ID and source name in bridge source ID",
 | 
				
			||||||
 | 
					                "pr": 162
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Add PancakeSwapFeature",
 | 
				
			||||||
 | 
					                "pr": 164
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Remove TokenSpender/AllowanceTarget/greedy tokens stuff",
 | 
				
			||||||
 | 
					                "pr": 164
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Added Nerve in BridgeAdapter",
 | 
				
			||||||
 | 
					                "pr": 181
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Delete TokenSpenderFeature",
 | 
				
			||||||
 | 
					                "pr": 189
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Fix PancakeSwapFeature BakerySwap swap selector",
 | 
				
			||||||
 | 
					                "pr": 190
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "timestamp": 1617311315
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "version": "0.20.0",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Add `MooniswapLiquidityProvider`",
 | 
				
			||||||
 | 
					                "pr": 143
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Emit `LiquidityProviderFill` event in `CurveLiquidityProvider`",
 | 
				
			||||||
 | 
					                "pr": 143
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Add BatchFillNativeOrdersFeature and MultiplexFeature",
 | 
				
			||||||
 | 
					                "pr": 140
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Export MultiplexFeatureContract",
 | 
				
			||||||
 | 
					                "pr": 168
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "timestamp": 1616005394
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "version": "0.19.0",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Add `CurveLiquidityProvider` and misc refactors",
 | 
				
			||||||
 | 
					                "pr": 127
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Export `CurveLiquidityProviderContract`",
 | 
				
			||||||
 | 
					                "pr": 144
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Add `DodoV2`",
 | 
				
			||||||
 | 
					                "pr": 152
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Add `Linkswap`",
 | 
				
			||||||
 | 
					                "pr": 153
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "refund ETH with no gas limit in FQT",
 | 
				
			||||||
 | 
					                "pr": 155
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Added an opt-in `PositiveSlippageAffiliateFee`",
 | 
				
			||||||
 | 
					                "pr": 101
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "timestamp": 1614141718
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "version": "0.18.2",
 | 
					        "version": "0.18.2",
 | 
				
			||||||
        "changes": [
 | 
					        "changes": [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,57 @@ Edit the package's CHANGELOG.json file only.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v0.22.0 - _April 26, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Add order signer registry to NativeOrdersFeature (#195)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v0.21.1 - _April 12, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Dependencies updated
 | 
				
			||||||
 | 
					    * BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap) (#208)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v0.21.0 - _April 1, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Encoding protocol ID and source name in bridge source ID (#162)
 | 
				
			||||||
 | 
					    * Add PancakeSwapFeature (#164)
 | 
				
			||||||
 | 
					    * Remove TokenSpender/AllowanceTarget/greedy tokens stuff (#164)
 | 
				
			||||||
 | 
					    * Added Nerve in BridgeAdapter (#181)
 | 
				
			||||||
 | 
					    * Delete TokenSpenderFeature (#189)
 | 
				
			||||||
 | 
					    * Fix PancakeSwapFeature BakerySwap swap selector (#190)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v0.20.0 - _March 17, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Add `MooniswapLiquidityProvider` (#143)
 | 
				
			||||||
 | 
					    * Emit `LiquidityProviderFill` event in `CurveLiquidityProvider` (#143)
 | 
				
			||||||
 | 
					    * Add BatchFillNativeOrdersFeature and MultiplexFeature (#140)
 | 
				
			||||||
 | 
					    * Export MultiplexFeatureContract (#168)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v0.19.0 - _February 24, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Add `CurveLiquidityProvider` and misc refactors (#127)
 | 
				
			||||||
 | 
					    * Export `CurveLiquidityProviderContract` (#144)
 | 
				
			||||||
 | 
					    * Add `DodoV2` (#152)
 | 
				
			||||||
 | 
					    * Add `Linkswap` (#153)
 | 
				
			||||||
 | 
					    * refund ETH with no gas limit in FQT (#155)
 | 
				
			||||||
 | 
					    * Added an opt-in `PositiveSlippageAffiliateFee` (#101)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v0.18.2 - _February 10, 2021_
 | 
					## v0.18.2 - _February 10, 2021_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Update FQT for v4 native orders (#104)
 | 
					    * Update FQT for v4 native orders (#104)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,26 +20,31 @@
 | 
				
			|||||||
pragma solidity ^0.6.5;
 | 
					pragma solidity ^0.6.5;
 | 
				
			||||||
pragma experimental ABIEncoderV2;
 | 
					pragma experimental ABIEncoderV2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "./features/IOwnableFeature.sol";
 | 
					import "./features/interfaces/IOwnableFeature.sol";
 | 
				
			||||||
import "./features/ISimpleFunctionRegistryFeature.sol";
 | 
					import "./features/interfaces/ISimpleFunctionRegistryFeature.sol";
 | 
				
			||||||
import "./features/ITokenSpenderFeature.sol";
 | 
					import "./features/interfaces/ITokenSpenderFeature.sol";
 | 
				
			||||||
import "./features/ITransformERC20Feature.sol";
 | 
					import "./features/interfaces/ITransformERC20Feature.sol";
 | 
				
			||||||
import "./features/IMetaTransactionsFeature.sol";
 | 
					import "./features/interfaces/IMetaTransactionsFeature.sol";
 | 
				
			||||||
import "./features/IUniswapFeature.sol";
 | 
					import "./features/interfaces/IUniswapFeature.sol";
 | 
				
			||||||
import "./features/ILiquidityProviderFeature.sol";
 | 
					import "./features/interfaces/IPancakeSwapFeature.sol";
 | 
				
			||||||
import "./features/INativeOrdersFeature.sol";
 | 
					import "./features/interfaces/ILiquidityProviderFeature.sol";
 | 
				
			||||||
 | 
					import "./features/interfaces/INativeOrdersFeature.sol";
 | 
				
			||||||
 | 
					import "./features/interfaces/IBatchFillNativeOrdersFeature.sol";
 | 
				
			||||||
 | 
					import "./features/interfaces/IMultiplexFeature.sol";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @dev Interface for a fully featured Exchange Proxy.
 | 
					/// @dev Interface for a fully featured Exchange Proxy.
 | 
				
			||||||
interface IZeroEx is
 | 
					interface IZeroEx is
 | 
				
			||||||
    IOwnableFeature,
 | 
					    IOwnableFeature,
 | 
				
			||||||
    ISimpleFunctionRegistryFeature,
 | 
					    ISimpleFunctionRegistryFeature,
 | 
				
			||||||
    ITokenSpenderFeature,
 | 
					 | 
				
			||||||
    ITransformERC20Feature,
 | 
					    ITransformERC20Feature,
 | 
				
			||||||
    IMetaTransactionsFeature,
 | 
					    IMetaTransactionsFeature,
 | 
				
			||||||
    IUniswapFeature,
 | 
					    IUniswapFeature,
 | 
				
			||||||
 | 
					    IPancakeSwapFeature,
 | 
				
			||||||
    ILiquidityProviderFeature,
 | 
					    ILiquidityProviderFeature,
 | 
				
			||||||
    INativeOrdersFeature
 | 
					    INativeOrdersFeature,
 | 
				
			||||||
 | 
					    IBatchFillNativeOrdersFeature,
 | 
				
			||||||
 | 
					    IMultiplexFeature
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // solhint-disable state-visibility
 | 
					    // solhint-disable state-visibility
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,6 +88,21 @@ library LibNativeOrdersRichErrors {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function InvalidSignerError(
 | 
				
			||||||
 | 
					        address maker,
 | 
				
			||||||
 | 
					        address signer
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        internal
 | 
				
			||||||
 | 
					        pure
 | 
				
			||||||
 | 
					        returns (bytes memory)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return abi.encodeWithSelector(
 | 
				
			||||||
 | 
					            bytes4(keccak256("InvalidSignerError(address,address)")),
 | 
				
			||||||
 | 
					            maker,
 | 
				
			||||||
 | 
					            signer
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function OrderNotFillableBySenderError(
 | 
					    function OrderNotFillableBySenderError(
 | 
				
			||||||
        bytes32 orderHash,
 | 
					        bytes32 orderHash,
 | 
				
			||||||
        address sender,
 | 
					        address sender,
 | 
				
			||||||
@@ -170,4 +185,21 @@ library LibNativeOrdersRichErrors {
 | 
				
			|||||||
            maker
 | 
					            maker
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function BatchFillIncompleteError(
 | 
				
			||||||
 | 
					        bytes32 orderHash,
 | 
				
			||||||
 | 
					        uint256 takerTokenFilledAmount,
 | 
				
			||||||
 | 
					        uint256 takerTokenFillAmount
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        internal
 | 
				
			||||||
 | 
					        pure
 | 
				
			||||||
 | 
					        returns (bytes memory)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return abi.encodeWithSelector(
 | 
				
			||||||
 | 
					            bytes4(keccak256("BatchFillIncompleteError(bytes32,uint256,uint256)")),
 | 
				
			||||||
 | 
					            orderHash,
 | 
				
			||||||
 | 
					            takerTokenFilledAmount,
 | 
				
			||||||
 | 
					            takerTokenFillAmount
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,56 +0,0 @@
 | 
				
			|||||||
// SPDX-License-Identifier: Apache-2.0
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Copyright 2020 ZeroEx Intl.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
  you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
  You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
  See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
  limitations under the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pragma solidity ^0.6.5;
 | 
					 | 
				
			||||||
pragma experimental ABIEncoderV2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
					 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/v06/AuthorizableV06.sol";
 | 
					 | 
				
			||||||
import "../errors/LibSpenderRichErrors.sol";
 | 
					 | 
				
			||||||
import "./IAllowanceTarget.sol";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// @dev The allowance target for the TokenSpender feature.
 | 
					 | 
				
			||||||
contract AllowanceTarget is
 | 
					 | 
				
			||||||
    IAllowanceTarget,
 | 
					 | 
				
			||||||
    AuthorizableV06
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // solhint-disable no-unused-vars,indent,no-empty-blocks
 | 
					 | 
				
			||||||
    using LibRichErrorsV06 for bytes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Execute an arbitrary call. Only an authority can call this.
 | 
					 | 
				
			||||||
    /// @param target The call target.
 | 
					 | 
				
			||||||
    /// @param callData The call data.
 | 
					 | 
				
			||||||
    /// @return resultData The data returned by the call.
 | 
					 | 
				
			||||||
    function executeCall(
 | 
					 | 
				
			||||||
        address payable target,
 | 
					 | 
				
			||||||
        bytes calldata callData
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        external
 | 
					 | 
				
			||||||
        override
 | 
					 | 
				
			||||||
        onlyAuthorized
 | 
					 | 
				
			||||||
        returns (bytes memory resultData)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        bool success;
 | 
					 | 
				
			||||||
        (success, resultData) = target.call(callData);
 | 
					 | 
				
			||||||
        if (!success) {
 | 
					 | 
				
			||||||
            resultData.rrevert();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -20,6 +20,9 @@
 | 
				
			|||||||
pragma solidity ^0.6.5;
 | 
					pragma solidity ^0.6.5;
 | 
				
			||||||
pragma experimental ABIEncoderV2;
 | 
					pragma experimental ABIEncoderV2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
				
			||||||
 | 
					import "../vendor/ILiquidityProvider.sol";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface ILiquidityProviderSandbox {
 | 
					interface ILiquidityProviderSandbox {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,9 +35,9 @@ interface ILiquidityProviderSandbox {
 | 
				
			|||||||
    /// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
 | 
					    /// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
 | 
				
			||||||
    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
					    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
				
			||||||
    function executeSellTokenForToken(
 | 
					    function executeSellTokenForToken(
 | 
				
			||||||
        address provider,
 | 
					        ILiquidityProvider provider,
 | 
				
			||||||
        address inputToken,
 | 
					        IERC20TokenV06 inputToken,
 | 
				
			||||||
        address outputToken,
 | 
					        IERC20TokenV06 outputToken,
 | 
				
			||||||
        address recipient,
 | 
					        address recipient,
 | 
				
			||||||
        uint256 minBuyAmount,
 | 
					        uint256 minBuyAmount,
 | 
				
			||||||
        bytes calldata auxiliaryData
 | 
					        bytes calldata auxiliaryData
 | 
				
			||||||
@@ -49,8 +52,8 @@ interface ILiquidityProviderSandbox {
 | 
				
			|||||||
    /// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
 | 
					    /// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
 | 
				
			||||||
    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
					    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
				
			||||||
    function executeSellEthForToken(
 | 
					    function executeSellEthForToken(
 | 
				
			||||||
        address provider,
 | 
					        ILiquidityProvider provider,
 | 
				
			||||||
        address outputToken,
 | 
					        IERC20TokenV06 outputToken,
 | 
				
			||||||
        address recipient,
 | 
					        address recipient,
 | 
				
			||||||
        uint256 minBuyAmount,
 | 
					        uint256 minBuyAmount,
 | 
				
			||||||
        bytes calldata auxiliaryData
 | 
					        bytes calldata auxiliaryData
 | 
				
			||||||
@@ -65,8 +68,8 @@ interface ILiquidityProviderSandbox {
 | 
				
			|||||||
    /// @param minBuyAmount The minimum acceptable amount of ETH to buy.
 | 
					    /// @param minBuyAmount The minimum acceptable amount of ETH to buy.
 | 
				
			||||||
    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
					    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
				
			||||||
    function executeSellTokenForEth(
 | 
					    function executeSellTokenForEth(
 | 
				
			||||||
        address provider,
 | 
					        ILiquidityProvider provider,
 | 
				
			||||||
        address inputToken,
 | 
					        IERC20TokenV06 inputToken,
 | 
				
			||||||
        address recipient,
 | 
					        address recipient,
 | 
				
			||||||
        uint256 minBuyAmount,
 | 
					        uint256 minBuyAmount,
 | 
				
			||||||
        bytes calldata auxiliaryData
 | 
					        bytes calldata auxiliaryData
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@ pragma experimental ABIEncoderV2;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
					import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibOwnableRichErrorsV06.sol";
 | 
					import "@0x/contracts-utils/contracts/src/v06/errors/LibOwnableRichErrorsV06.sol";
 | 
				
			||||||
 | 
					import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
				
			||||||
import "../vendor/ILiquidityProvider.sol";
 | 
					import "../vendor/ILiquidityProvider.sol";
 | 
				
			||||||
import "../vendor/v3/IERC20Bridge.sol";
 | 
					import "../vendor/v3/IERC20Bridge.sol";
 | 
				
			||||||
import "./ILiquidityProviderSandbox.sol";
 | 
					import "./ILiquidityProviderSandbox.sol";
 | 
				
			||||||
@@ -58,9 +59,9 @@ contract LiquidityProviderSandbox is
 | 
				
			|||||||
    /// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
 | 
					    /// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
 | 
				
			||||||
    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
					    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
				
			||||||
    function executeSellTokenForToken(
 | 
					    function executeSellTokenForToken(
 | 
				
			||||||
        address provider,
 | 
					        ILiquidityProvider provider,
 | 
				
			||||||
        address inputToken,
 | 
					        IERC20TokenV06 inputToken,
 | 
				
			||||||
        address outputToken,
 | 
					        IERC20TokenV06 outputToken,
 | 
				
			||||||
        address recipient,
 | 
					        address recipient,
 | 
				
			||||||
        uint256 minBuyAmount,
 | 
					        uint256 minBuyAmount,
 | 
				
			||||||
        bytes calldata auxiliaryData
 | 
					        bytes calldata auxiliaryData
 | 
				
			||||||
@@ -69,7 +70,7 @@ contract LiquidityProviderSandbox is
 | 
				
			|||||||
        onlyOwner
 | 
					        onlyOwner
 | 
				
			||||||
        override
 | 
					        override
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ILiquidityProvider(provider).sellTokenForToken(
 | 
					        provider.sellTokenForToken(
 | 
				
			||||||
            inputToken,
 | 
					            inputToken,
 | 
				
			||||||
            outputToken,
 | 
					            outputToken,
 | 
				
			||||||
            recipient,
 | 
					            recipient,
 | 
				
			||||||
@@ -86,8 +87,8 @@ contract LiquidityProviderSandbox is
 | 
				
			|||||||
    /// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
 | 
					    /// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
 | 
				
			||||||
    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
					    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
				
			||||||
    function executeSellEthForToken(
 | 
					    function executeSellEthForToken(
 | 
				
			||||||
        address provider,
 | 
					        ILiquidityProvider provider,
 | 
				
			||||||
        address outputToken,
 | 
					        IERC20TokenV06 outputToken,
 | 
				
			||||||
        address recipient,
 | 
					        address recipient,
 | 
				
			||||||
        uint256 minBuyAmount,
 | 
					        uint256 minBuyAmount,
 | 
				
			||||||
        bytes calldata auxiliaryData
 | 
					        bytes calldata auxiliaryData
 | 
				
			||||||
@@ -96,7 +97,7 @@ contract LiquidityProviderSandbox is
 | 
				
			|||||||
        onlyOwner
 | 
					        onlyOwner
 | 
				
			||||||
        override
 | 
					        override
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ILiquidityProvider(provider).sellEthForToken(
 | 
					        provider.sellEthForToken(
 | 
				
			||||||
            outputToken,
 | 
					            outputToken,
 | 
				
			||||||
            recipient,
 | 
					            recipient,
 | 
				
			||||||
            minBuyAmount,
 | 
					            minBuyAmount,
 | 
				
			||||||
@@ -112,8 +113,8 @@ contract LiquidityProviderSandbox is
 | 
				
			|||||||
    /// @param minBuyAmount The minimum acceptable amount of ETH to buy.
 | 
					    /// @param minBuyAmount The minimum acceptable amount of ETH to buy.
 | 
				
			||||||
    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
					    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
				
			||||||
    function executeSellTokenForEth(
 | 
					    function executeSellTokenForEth(
 | 
				
			||||||
        address provider,
 | 
					        ILiquidityProvider provider,
 | 
				
			||||||
        address inputToken,
 | 
					        IERC20TokenV06 inputToken,
 | 
				
			||||||
        address recipient,
 | 
					        address recipient,
 | 
				
			||||||
        uint256 minBuyAmount,
 | 
					        uint256 minBuyAmount,
 | 
				
			||||||
        bytes calldata auxiliaryData
 | 
					        bytes calldata auxiliaryData
 | 
				
			||||||
@@ -122,7 +123,7 @@ contract LiquidityProviderSandbox is
 | 
				
			|||||||
        onlyOwner
 | 
					        onlyOwner
 | 
				
			||||||
        override
 | 
					        override
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ILiquidityProvider(provider).sellTokenForEth(
 | 
					        provider.sellTokenForEth(
 | 
				
			||||||
            inputToken,
 | 
					            inputToken,
 | 
				
			||||||
            payable(recipient),
 | 
					            payable(recipient),
 | 
				
			||||||
            minBuyAmount,
 | 
					            minBuyAmount,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,198 @@
 | 
				
			|||||||
 | 
					// 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-utils/contracts/src/v06/errors/LibRichErrorsV06.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 "../migrations/LibMigrate.sol";
 | 
				
			||||||
 | 
					import "./interfaces/IFeature.sol";
 | 
				
			||||||
 | 
					import "./interfaces/IBatchFillNativeOrdersFeature.sol";
 | 
				
			||||||
 | 
					import "./interfaces/INativeOrdersFeature.sol";
 | 
				
			||||||
 | 
					import "./libs/LibNativeOrder.sol";
 | 
				
			||||||
 | 
					import "./libs/LibSignature.sol";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @dev Feature for batch/market filling limit and RFQ orders.
 | 
				
			||||||
 | 
					contract BatchFillNativeOrdersFeature is
 | 
				
			||||||
 | 
					    IFeature,
 | 
				
			||||||
 | 
					    IBatchFillNativeOrdersFeature,
 | 
				
			||||||
 | 
					    FixinCommon,
 | 
				
			||||||
 | 
					    FixinEIP712
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    using LibSafeMathV06 for uint128;
 | 
				
			||||||
 | 
					    using LibSafeMathV06 for uint256;
 | 
				
			||||||
 | 
					    using LibRichErrorsV06 for bytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(address zeroExAddress)
 | 
				
			||||||
 | 
					        public
 | 
				
			||||||
 | 
					        FixinEIP712(zeroExAddress)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // solhint-disable no-empty-blocks
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @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.batchFillLimitOrders.selector);
 | 
				
			||||||
 | 
					        _registerFeatureFunction(this.batchFillRfqOrders.selector);
 | 
				
			||||||
 | 
					        return LibMigrate.MIGRATE_SUCCESS;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @dev Fills multiple limit orders.
 | 
				
			||||||
 | 
					    /// @param orders Array of limit orders.
 | 
				
			||||||
 | 
					    /// @param signatures Array of signatures corresponding to each order.
 | 
				
			||||||
 | 
					    /// @param takerTokenFillAmounts Array of desired amounts to fill each order.
 | 
				
			||||||
 | 
					    /// @param revertIfIncomplete If true, reverts if this function fails to
 | 
				
			||||||
 | 
					    ///        fill the full fill amount for any individual order.
 | 
				
			||||||
 | 
					    /// @return takerTokenFilledAmounts Array of amounts filled, in taker token.
 | 
				
			||||||
 | 
					    /// @return makerTokenFilledAmounts Array of amounts filled, in maker token.
 | 
				
			||||||
 | 
					    function batchFillLimitOrders(
 | 
				
			||||||
 | 
					        LibNativeOrder.LimitOrder[] calldata orders,
 | 
				
			||||||
 | 
					        LibSignature.Signature[] calldata signatures,
 | 
				
			||||||
 | 
					        uint128[] calldata takerTokenFillAmounts,
 | 
				
			||||||
 | 
					        bool revertIfIncomplete
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        external
 | 
				
			||||||
 | 
					        payable
 | 
				
			||||||
 | 
					        override
 | 
				
			||||||
 | 
					        returns (
 | 
				
			||||||
 | 
					            uint128[] memory takerTokenFilledAmounts,
 | 
				
			||||||
 | 
					            uint128[] memory makerTokenFilledAmounts
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        require(
 | 
				
			||||||
 | 
					            orders.length == signatures.length && orders.length == takerTokenFillAmounts.length,
 | 
				
			||||||
 | 
					            'BatchFillNativeOrdersFeature::batchFillLimitOrders/MISMATCHED_ARRAY_LENGTHS'
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        takerTokenFilledAmounts = new uint128[](orders.length);
 | 
				
			||||||
 | 
					        makerTokenFilledAmounts = new uint128[](orders.length);
 | 
				
			||||||
 | 
					        uint256 protocolFee = uint256(INativeOrdersFeature(address(this)).getProtocolFeeMultiplier())
 | 
				
			||||||
 | 
					            .safeMul(tx.gasprice);
 | 
				
			||||||
 | 
					        uint256 ethProtocolFeePaid;
 | 
				
			||||||
 | 
					        for (uint256 i = 0; i != orders.length; i++) {
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					                INativeOrdersFeature(address(this))._fillLimitOrder
 | 
				
			||||||
 | 
					                    (
 | 
				
			||||||
 | 
					                        orders[i],
 | 
				
			||||||
 | 
					                        signatures[i],
 | 
				
			||||||
 | 
					                        takerTokenFillAmounts[i],
 | 
				
			||||||
 | 
					                        msg.sender,
 | 
				
			||||||
 | 
					                        msg.sender
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // Update amounts filled.
 | 
				
			||||||
 | 
					                (takerTokenFilledAmounts[i], makerTokenFilledAmounts[i]) =
 | 
				
			||||||
 | 
					                    (takerTokenFilledAmount, makerTokenFilledAmount);
 | 
				
			||||||
 | 
					                ethProtocolFeePaid = ethProtocolFeePaid.safeAdd(protocolFee);
 | 
				
			||||||
 | 
					            } catch {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (
 | 
				
			||||||
 | 
					                revertIfIncomplete &&
 | 
				
			||||||
 | 
					                takerTokenFilledAmounts[i] < takerTokenFillAmounts[i]
 | 
				
			||||||
 | 
					            ) {
 | 
				
			||||||
 | 
					                bytes32 orderHash = _getEIP712Hash(
 | 
				
			||||||
 | 
					                    LibNativeOrder.getLimitOrderStructHash(orders[i])
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                // Did not fill the amount requested.
 | 
				
			||||||
 | 
					                LibNativeOrdersRichErrors.BatchFillIncompleteError(
 | 
				
			||||||
 | 
					                    orderHash,
 | 
				
			||||||
 | 
					                    takerTokenFilledAmounts[i],
 | 
				
			||||||
 | 
					                    takerTokenFillAmounts[i]
 | 
				
			||||||
 | 
					                ).rrevert();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        LibNativeOrder.refundExcessProtocolFeeToSender(ethProtocolFeePaid);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @dev Fills multiple RFQ orders.
 | 
				
			||||||
 | 
					    /// @param orders Array of RFQ orders.
 | 
				
			||||||
 | 
					    /// @param signatures Array of signatures corresponding to each order.
 | 
				
			||||||
 | 
					    /// @param takerTokenFillAmounts Array of desired amounts to fill each order.
 | 
				
			||||||
 | 
					    /// @param revertIfIncomplete If true, reverts if this function fails to
 | 
				
			||||||
 | 
					    ///        fill the full fill amount for any individual order.
 | 
				
			||||||
 | 
					    /// @return takerTokenFilledAmounts Array of amounts filled, in taker token.
 | 
				
			||||||
 | 
					    /// @return makerTokenFilledAmounts Array of amounts filled, in maker token.
 | 
				
			||||||
 | 
					    function batchFillRfqOrders(
 | 
				
			||||||
 | 
					        LibNativeOrder.RfqOrder[] calldata orders,
 | 
				
			||||||
 | 
					        LibSignature.Signature[] calldata signatures,
 | 
				
			||||||
 | 
					        uint128[] calldata takerTokenFillAmounts,
 | 
				
			||||||
 | 
					        bool revertIfIncomplete
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        external
 | 
				
			||||||
 | 
					        override
 | 
				
			||||||
 | 
					        returns (
 | 
				
			||||||
 | 
					            uint128[] memory takerTokenFilledAmounts,
 | 
				
			||||||
 | 
					            uint128[] memory makerTokenFilledAmounts
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        require(
 | 
				
			||||||
 | 
					            orders.length == signatures.length && orders.length == takerTokenFillAmounts.length,
 | 
				
			||||||
 | 
					            'BatchFillNativeOrdersFeature::batchFillRfqOrders/MISMATCHED_ARRAY_LENGTHS'
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        takerTokenFilledAmounts = new uint128[](orders.length);
 | 
				
			||||||
 | 
					        makerTokenFilledAmounts = new uint128[](orders.length);
 | 
				
			||||||
 | 
					        for (uint256 i = 0; i != orders.length; i++) {
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					                INativeOrdersFeature(address(this))._fillRfqOrder
 | 
				
			||||||
 | 
					                    (
 | 
				
			||||||
 | 
					                        orders[i],
 | 
				
			||||||
 | 
					                        signatures[i],
 | 
				
			||||||
 | 
					                        takerTokenFillAmounts[i],
 | 
				
			||||||
 | 
					                        msg.sender
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // Update amounts filled.
 | 
				
			||||||
 | 
					                (takerTokenFilledAmounts[i], makerTokenFilledAmounts[i]) =
 | 
				
			||||||
 | 
					                    (takerTokenFilledAmount, makerTokenFilledAmount);
 | 
				
			||||||
 | 
					            } catch {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (
 | 
				
			||||||
 | 
					                revertIfIncomplete &&
 | 
				
			||||||
 | 
					                takerTokenFilledAmounts[i] < takerTokenFillAmounts[i]
 | 
				
			||||||
 | 
					            ) {
 | 
				
			||||||
 | 
					                // Did not fill the amount requested.
 | 
				
			||||||
 | 
					                bytes32 orderHash = _getEIP712Hash(
 | 
				
			||||||
 | 
					                    LibNativeOrder.getRfqOrderStructHash(orders[i])
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                LibNativeOrdersRichErrors.BatchFillIncompleteError(
 | 
				
			||||||
 | 
					                    orderHash,
 | 
				
			||||||
 | 
					                    takerTokenFilledAmounts[i],
 | 
				
			||||||
 | 
					                    takerTokenFillAmounts[i]
 | 
				
			||||||
 | 
					                ).rrevert();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -23,7 +23,7 @@ pragma experimental ABIEncoderV2;
 | 
				
			|||||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
					import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
				
			||||||
import "../migrations/LibBootstrap.sol";
 | 
					import "../migrations/LibBootstrap.sol";
 | 
				
			||||||
import "../storage/LibProxyStorage.sol";
 | 
					import "../storage/LibProxyStorage.sol";
 | 
				
			||||||
import "./IBootstrapFeature.sol";
 | 
					import "./interfaces/IBootstrapFeature.sol";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @dev Detachable `bootstrap()` feature.
 | 
					/// @dev Detachable `bootstrap()` feature.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,14 +23,16 @@ pragma experimental ABIEncoderV2;
 | 
				
			|||||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
					import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
					import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
					import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
				
			||||||
 | 
					import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
				
			||||||
import "../errors/LibLiquidityProviderRichErrors.sol";
 | 
					import "../errors/LibLiquidityProviderRichErrors.sol";
 | 
				
			||||||
import "../external/ILiquidityProviderSandbox.sol";
 | 
					import "../external/ILiquidityProviderSandbox.sol";
 | 
				
			||||||
import "../external/LiquidityProviderSandbox.sol";
 | 
					import "../external/LiquidityProviderSandbox.sol";
 | 
				
			||||||
import "../fixins/FixinCommon.sol";
 | 
					import "../fixins/FixinCommon.sol";
 | 
				
			||||||
import "../fixins/FixinTokenSpender.sol";
 | 
					import "../fixins/FixinTokenSpender.sol";
 | 
				
			||||||
import "../migrations/LibMigrate.sol";
 | 
					import "../migrations/LibMigrate.sol";
 | 
				
			||||||
import "./IFeature.sol";
 | 
					import "../transformers/LibERC20Transformer.sol";
 | 
				
			||||||
import "./ILiquidityProviderFeature.sol";
 | 
					import "./interfaces/IFeature.sol";
 | 
				
			||||||
 | 
					import "./interfaces/ILiquidityProviderFeature.sol";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
contract LiquidityProviderFeature is
 | 
					contract LiquidityProviderFeature is
 | 
				
			||||||
@@ -45,27 +47,14 @@ contract LiquidityProviderFeature is
 | 
				
			|||||||
    /// @dev Name of this feature.
 | 
					    /// @dev Name of this feature.
 | 
				
			||||||
    string public constant override FEATURE_NAME = "LiquidityProviderFeature";
 | 
					    string public constant override FEATURE_NAME = "LiquidityProviderFeature";
 | 
				
			||||||
    /// @dev Version of this feature.
 | 
					    /// @dev Version of this feature.
 | 
				
			||||||
    uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 2);
 | 
					    uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev ETH pseudo-token address.
 | 
					 | 
				
			||||||
    address constant internal ETH_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
 | 
					 | 
				
			||||||
    /// @dev The sandbox contract address.
 | 
					    /// @dev The sandbox contract address.
 | 
				
			||||||
    ILiquidityProviderSandbox public immutable sandbox;
 | 
					    ILiquidityProviderSandbox public immutable sandbox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev Event for data pipeline.
 | 
					    constructor(LiquidityProviderSandbox sandbox_)
 | 
				
			||||||
    event LiquidityProviderSwap(
 | 
					 | 
				
			||||||
        address inputToken,
 | 
					 | 
				
			||||||
        address outputToken,
 | 
					 | 
				
			||||||
        uint256 inputTokenAmount,
 | 
					 | 
				
			||||||
        uint256 outputTokenAmount,
 | 
					 | 
				
			||||||
        address provider,
 | 
					 | 
				
			||||||
        address recipient
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    constructor(LiquidityProviderSandbox sandbox_, bytes32 greedyTokensBloomFilter)
 | 
					 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        FixinCommon()
 | 
					        FixinCommon()
 | 
				
			||||||
        FixinTokenSpender(greedyTokensBloomFilter)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        sandbox = sandbox_;
 | 
					        sandbox = sandbox_;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -95,9 +84,9 @@ contract LiquidityProviderFeature is
 | 
				
			|||||||
    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
					    /// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
 | 
				
			||||||
    /// @return boughtAmount The amount of `outputToken` bought.
 | 
					    /// @return boughtAmount The amount of `outputToken` bought.
 | 
				
			||||||
    function sellToLiquidityProvider(
 | 
					    function sellToLiquidityProvider(
 | 
				
			||||||
        address inputToken,
 | 
					        IERC20TokenV06 inputToken,
 | 
				
			||||||
        address outputToken,
 | 
					        IERC20TokenV06 outputToken,
 | 
				
			||||||
        address payable provider,
 | 
					        ILiquidityProvider provider,
 | 
				
			||||||
        address recipient,
 | 
					        address recipient,
 | 
				
			||||||
        uint256 sellAmount,
 | 
					        uint256 sellAmount,
 | 
				
			||||||
        uint256 minBuyAmount,
 | 
					        uint256 minBuyAmount,
 | 
				
			||||||
@@ -114,21 +103,21 @@ contract LiquidityProviderFeature is
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Forward all attached ETH to the provider.
 | 
					        // Forward all attached ETH to the provider.
 | 
				
			||||||
        if (msg.value > 0) {
 | 
					        if (msg.value > 0) {
 | 
				
			||||||
            provider.transfer(msg.value);
 | 
					            payable(address(provider)).transfer(msg.value);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (inputToken != ETH_TOKEN_ADDRESS) {
 | 
					        if (!LibERC20Transformer.isTokenETH(inputToken)) {
 | 
				
			||||||
            // Transfer input ERC20 tokens to the provider.
 | 
					            // Transfer input ERC20 tokens to the provider.
 | 
				
			||||||
            _transferERC20Tokens(
 | 
					            _transferERC20Tokens(
 | 
				
			||||||
                IERC20TokenV06(inputToken),
 | 
					                inputToken,
 | 
				
			||||||
                msg.sender,
 | 
					                msg.sender,
 | 
				
			||||||
                provider,
 | 
					                address(provider),
 | 
				
			||||||
                sellAmount
 | 
					                sellAmount
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (inputToken == ETH_TOKEN_ADDRESS) {
 | 
					        if (LibERC20Transformer.isTokenETH(inputToken)) {
 | 
				
			||||||
            uint256 balanceBefore = IERC20TokenV06(outputToken).balanceOf(recipient);
 | 
					            uint256 balanceBefore = outputToken.balanceOf(recipient);
 | 
				
			||||||
            sandbox.executeSellEthForToken(
 | 
					            sandbox.executeSellEthForToken(
 | 
				
			||||||
                provider,
 | 
					                provider,
 | 
				
			||||||
                outputToken,
 | 
					                outputToken,
 | 
				
			||||||
@@ -137,7 +126,7 @@ contract LiquidityProviderFeature is
 | 
				
			|||||||
                auxiliaryData
 | 
					                auxiliaryData
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            boughtAmount = IERC20TokenV06(outputToken).balanceOf(recipient).safeSub(balanceBefore);
 | 
					            boughtAmount = IERC20TokenV06(outputToken).balanceOf(recipient).safeSub(balanceBefore);
 | 
				
			||||||
        } else if (outputToken == ETH_TOKEN_ADDRESS) {
 | 
					        } else if (LibERC20Transformer.isTokenETH(outputToken)) {
 | 
				
			||||||
            uint256 balanceBefore = recipient.balance;
 | 
					            uint256 balanceBefore = recipient.balance;
 | 
				
			||||||
            sandbox.executeSellTokenForEth(
 | 
					            sandbox.executeSellTokenForEth(
 | 
				
			||||||
                provider,
 | 
					                provider,
 | 
				
			||||||
@@ -148,7 +137,7 @@ contract LiquidityProviderFeature is
 | 
				
			|||||||
            );
 | 
					            );
 | 
				
			||||||
            boughtAmount = recipient.balance.safeSub(balanceBefore);
 | 
					            boughtAmount = recipient.balance.safeSub(balanceBefore);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            uint256 balanceBefore = IERC20TokenV06(outputToken).balanceOf(recipient);
 | 
					            uint256 balanceBefore = outputToken.balanceOf(recipient);
 | 
				
			||||||
            sandbox.executeSellTokenForToken(
 | 
					            sandbox.executeSellTokenForToken(
 | 
				
			||||||
                provider,
 | 
					                provider,
 | 
				
			||||||
                inputToken,
 | 
					                inputToken,
 | 
				
			||||||
@@ -157,14 +146,14 @@ contract LiquidityProviderFeature is
 | 
				
			|||||||
                minBuyAmount,
 | 
					                minBuyAmount,
 | 
				
			||||||
                auxiliaryData
 | 
					                auxiliaryData
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            boughtAmount = IERC20TokenV06(outputToken).balanceOf(recipient).safeSub(balanceBefore);
 | 
					            boughtAmount = outputToken.balanceOf(recipient).safeSub(balanceBefore);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (boughtAmount < minBuyAmount) {
 | 
					        if (boughtAmount < minBuyAmount) {
 | 
				
			||||||
            LibLiquidityProviderRichErrors.LiquidityProviderIncompleteSellError(
 | 
					            LibLiquidityProviderRichErrors.LiquidityProviderIncompleteSellError(
 | 
				
			||||||
                provider,
 | 
					                address(provider),
 | 
				
			||||||
                outputToken,
 | 
					                address(outputToken),
 | 
				
			||||||
                inputToken,
 | 
					                address(inputToken),
 | 
				
			||||||
                sellAmount,
 | 
					                sellAmount,
 | 
				
			||||||
                boughtAmount,
 | 
					                boughtAmount,
 | 
				
			||||||
                minBuyAmount
 | 
					                minBuyAmount
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,11 +30,11 @@ import "../fixins/FixinTokenSpender.sol";
 | 
				
			|||||||
import "../fixins/FixinEIP712.sol";
 | 
					import "../fixins/FixinEIP712.sol";
 | 
				
			||||||
import "../migrations/LibMigrate.sol";
 | 
					import "../migrations/LibMigrate.sol";
 | 
				
			||||||
import "../storage/LibMetaTransactionsStorage.sol";
 | 
					import "../storage/LibMetaTransactionsStorage.sol";
 | 
				
			||||||
import "./IMetaTransactionsFeature.sol";
 | 
					import "./interfaces/IFeature.sol";
 | 
				
			||||||
import "./ITransformERC20Feature.sol";
 | 
					import "./interfaces/IMetaTransactionsFeature.sol";
 | 
				
			||||||
 | 
					import "./interfaces/INativeOrdersFeature.sol";
 | 
				
			||||||
 | 
					import "./interfaces/ITransformERC20Feature.sol";
 | 
				
			||||||
import "./libs/LibSignature.sol";
 | 
					import "./libs/LibSignature.sol";
 | 
				
			||||||
import "./IFeature.sol";
 | 
					 | 
				
			||||||
import "./INativeOrdersFeature.sol";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @dev MetaTransactions feature.
 | 
					/// @dev MetaTransactions feature.
 | 
				
			||||||
contract MetaTransactionsFeature is
 | 
					contract MetaTransactionsFeature is
 | 
				
			||||||
@@ -78,7 +78,7 @@ contract MetaTransactionsFeature is
 | 
				
			|||||||
    /// @dev Name of this feature.
 | 
					    /// @dev Name of this feature.
 | 
				
			||||||
    string public constant override FEATURE_NAME = "MetaTransactions";
 | 
					    string public constant override FEATURE_NAME = "MetaTransactions";
 | 
				
			||||||
    /// @dev Version of this feature.
 | 
					    /// @dev Version of this feature.
 | 
				
			||||||
    uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 0);
 | 
					    uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 1);
 | 
				
			||||||
    /// @dev EIP712 typehash of the `MetaTransactionData` struct.
 | 
					    /// @dev EIP712 typehash of the `MetaTransactionData` struct.
 | 
				
			||||||
    bytes32 public immutable MTX_EIP712_TYPEHASH = keccak256(
 | 
					    bytes32 public immutable MTX_EIP712_TYPEHASH = keccak256(
 | 
				
			||||||
        "MetaTransactionData("
 | 
					        "MetaTransactionData("
 | 
				
			||||||
@@ -105,11 +105,10 @@ contract MetaTransactionsFeature is
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(address zeroExAddress, bytes32 greedyTokensBloomFilter)
 | 
					    constructor(address zeroExAddress)
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        FixinCommon()
 | 
					        FixinCommon()
 | 
				
			||||||
        FixinEIP712(zeroExAddress)
 | 
					        FixinEIP712(zeroExAddress)
 | 
				
			||||||
        FixinTokenSpender(greedyTokensBloomFilter)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // solhint-disable-next-line no-empty-blocks
 | 
					        // solhint-disable-next-line no-empty-blocks
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										803
									
								
								contracts/zero-ex/contracts/src/features/MultiplexFeature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										803
									
								
								contracts/zero-ex/contracts/src/features/MultiplexFeature.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,803 @@
 | 
				
			|||||||
 | 
					// 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
 | 
				
			||||||
 | 
					            ))));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -26,8 +26,8 @@ import "../errors/LibOwnableRichErrors.sol";
 | 
				
			|||||||
import "../storage/LibOwnableStorage.sol";
 | 
					import "../storage/LibOwnableStorage.sol";
 | 
				
			||||||
import "../migrations/LibBootstrap.sol";
 | 
					import "../migrations/LibBootstrap.sol";
 | 
				
			||||||
import "../migrations/LibMigrate.sol";
 | 
					import "../migrations/LibMigrate.sol";
 | 
				
			||||||
import "./IFeature.sol";
 | 
					import "./interfaces/IFeature.sol";
 | 
				
			||||||
import "./IOwnableFeature.sol";
 | 
					import "./interfaces/IOwnableFeature.sol";
 | 
				
			||||||
import "./SimpleFunctionRegistryFeature.sol";
 | 
					import "./SimpleFunctionRegistryFeature.sol";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										470
									
								
								contracts/zero-ex/contracts/src/features/PancakeSwapFeature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										470
									
								
								contracts/zero-ex/contracts/src/features/PancakeSwapFeature.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,470 @@
 | 
				
			|||||||
 | 
					// 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 "../migrations/LibMigrate.sol";
 | 
				
			||||||
 | 
					import "../fixins/FixinCommon.sol";
 | 
				
			||||||
 | 
					import "./interfaces/IFeature.sol";
 | 
				
			||||||
 | 
					import "./interfaces/IPancakeSwapFeature.sol";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @dev VIP pancake fill functions.
 | 
				
			||||||
 | 
					contract PancakeSwapFeature is
 | 
				
			||||||
 | 
					    IFeature,
 | 
				
			||||||
 | 
					    IPancakeSwapFeature,
 | 
				
			||||||
 | 
					    FixinCommon
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// @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, 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.
 | 
				
			||||||
 | 
					    uint256 constant private ETH_TOKEN_ADDRESS_32 = 0x000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee;
 | 
				
			||||||
 | 
					    // Maximum token quantity that can be swapped against the PancakeSwapPair contract.
 | 
				
			||||||
 | 
					    uint256 constant private MAX_SWAP_AMOUNT = 2**112;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // bytes4(keccak256("executeCall(address,bytes)"))
 | 
				
			||||||
 | 
					    uint256 constant private ALLOWANCE_TARGET_EXECUTE_CALL_SELECTOR_32 = 0xbca8c7b500000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					    // bytes4(keccak256("getReserves()"))
 | 
				
			||||||
 | 
					    uint256 constant private PANCAKESWAP_PAIR_RESERVES_CALL_SELECTOR_32 = 0x0902f1ac00000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					    // bytes4(keccak256("swap(uint256,uint256,address,bytes)"))
 | 
				
			||||||
 | 
					    uint256 constant private PANCAKESWAP_PAIR_SWAP_CALL_SELECTOR_32 = 0x022c0d9f00000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					    // bytes4(keccak256("swap(uint256,uint256,address)"))
 | 
				
			||||||
 | 
					    uint256 constant private BAKERYSWAP_PAIR_SWAP_CALL_SELECTOR_32 = 0x6d9a640a00000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					    // bytes4(keccak256("transferFrom(address,address,uint256)"))
 | 
				
			||||||
 | 
					    uint256 constant private TRANSFER_FROM_CALL_SELECTOR_32 = 0x23b872dd00000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					    // bytes4(keccak256("allowance(address,address)"))
 | 
				
			||||||
 | 
					    uint256 constant private ALLOWANCE_CALL_SELECTOR_32 = 0xdd62ed3e00000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					    // bytes4(keccak256("withdraw(uint256)"))
 | 
				
			||||||
 | 
					    uint256 constant private WETH_WITHDRAW_CALL_SELECTOR_32 = 0x2e1a7d4d00000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					    // bytes4(keccak256("deposit()"))
 | 
				
			||||||
 | 
					    uint256 constant private WETH_DEPOSIT_CALL_SELECTOR_32 = 0xd0e30db000000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					    // bytes4(keccak256("transfer(address,uint256)"))
 | 
				
			||||||
 | 
					    uint256 constant private ERC20_TRANSFER_CALL_SELECTOR_32 = 0xa9059cbb00000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @dev Construct this contract.
 | 
				
			||||||
 | 
					    /// @param wbnb The WBNB contract.
 | 
				
			||||||
 | 
					    constructor(IEtherTokenV06 wbnb) public {
 | 
				
			||||||
 | 
					        WBNB = wbnb;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @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.sellToPancakeSwap.selector);
 | 
				
			||||||
 | 
					        return LibMigrate.MIGRATE_SUCCESS;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @dev Efficiently sell directly to pancake/BakerySwap/SushiSwap.
 | 
				
			||||||
 | 
					    /// @param tokens Sell path.
 | 
				
			||||||
 | 
					    /// @param sellAmount of `tokens[0]` Amount to sell.
 | 
				
			||||||
 | 
					    /// @param minBuyAmount Minimum amount of `tokens[-1]` to buy.
 | 
				
			||||||
 | 
					    /// @param fork The protocol fork to use.
 | 
				
			||||||
 | 
					    /// @return buyAmount Amount of `tokens[-1]` bought.
 | 
				
			||||||
 | 
					    function sellToPancakeSwap(
 | 
				
			||||||
 | 
					        IERC20TokenV06[] calldata tokens,
 | 
				
			||||||
 | 
					        uint256 sellAmount,
 | 
				
			||||||
 | 
					        uint256 minBuyAmount,
 | 
				
			||||||
 | 
					        ProtocolFork fork
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        external
 | 
				
			||||||
 | 
					        payable
 | 
				
			||||||
 | 
					        override
 | 
				
			||||||
 | 
					        returns (uint256 buyAmount)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        require(tokens.length > 1, "PancakeSwapFeature/InvalidTokensLength");
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Load immutables onto the stack.
 | 
				
			||||||
 | 
					            IEtherTokenV06 wbnb = WBNB;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Store some vars in memory to get around stack limits.
 | 
				
			||||||
 | 
					            assembly {
 | 
				
			||||||
 | 
					                // calldataload(mload(0xA00)) == first element of `tokens` array
 | 
				
			||||||
 | 
					                mstore(0xA00, add(calldataload(0x04), 0x24))
 | 
				
			||||||
 | 
					                // mload(0xA20) == fork
 | 
				
			||||||
 | 
					                mstore(0xA20, fork)
 | 
				
			||||||
 | 
					                // mload(0xA40) == WBNB
 | 
				
			||||||
 | 
					                mstore(0xA40, wbnb)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assembly {
 | 
				
			||||||
 | 
					            // numPairs == tokens.length - 1
 | 
				
			||||||
 | 
					            let numPairs := sub(calldataload(add(calldataload(0x04), 0x4)), 1)
 | 
				
			||||||
 | 
					            // We use the previous buy amount as the sell amount for the next
 | 
				
			||||||
 | 
					            // pair in a path. So for the first swap we want to set it to `sellAmount`.
 | 
				
			||||||
 | 
					            buyAmount := sellAmount
 | 
				
			||||||
 | 
					            let buyToken
 | 
				
			||||||
 | 
					            let nextPair := 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for {let i := 0} lt(i, numPairs) {i := add(i, 1)} {
 | 
				
			||||||
 | 
					                // sellToken = tokens[i]
 | 
				
			||||||
 | 
					                let sellToken := loadTokenAddress(i)
 | 
				
			||||||
 | 
					                // buyToken = tokens[i+1]
 | 
				
			||||||
 | 
					                buyToken := loadTokenAddress(add(i, 1))
 | 
				
			||||||
 | 
					                // The canonical ordering of this token pair.
 | 
				
			||||||
 | 
					                let pairOrder := lt(normalizeToken(sellToken), normalizeToken(buyToken))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Compute the pair address if it hasn't already been computed
 | 
				
			||||||
 | 
					                // from the last iteration.
 | 
				
			||||||
 | 
					                let pair := nextPair
 | 
				
			||||||
 | 
					                if iszero(pair) {
 | 
				
			||||||
 | 
					                    pair := computePairAddress(sellToken, buyToken)
 | 
				
			||||||
 | 
					                    nextPair := 0
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if iszero(i) {
 | 
				
			||||||
 | 
					                    // This is the first token in the path.
 | 
				
			||||||
 | 
					                    switch eq(sellToken, ETH_TOKEN_ADDRESS_32)
 | 
				
			||||||
 | 
					                        case 0 { // Not selling BNB. Selling an ERC20 instead.
 | 
				
			||||||
 | 
					                            // Make sure BNB was not attached to the call.
 | 
				
			||||||
 | 
					                            if gt(callvalue(), 0) {
 | 
				
			||||||
 | 
					                                revert(0, 0)
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            // For the first pair we need to transfer sellTokens into the
 | 
				
			||||||
 | 
					                            // pair contract.
 | 
				
			||||||
 | 
					                            moveTakerTokensTo(sellToken, pair, sellAmount)
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        default {
 | 
				
			||||||
 | 
					                            // If selling BNB, we need to wrap it to WBNB and transfer to the
 | 
				
			||||||
 | 
					                            // pair contract.
 | 
				
			||||||
 | 
					                            if iszero(eq(callvalue(), sellAmount)) {
 | 
				
			||||||
 | 
					                                revert(0, 0)
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            sellToken := mload(0xA40)// Re-assign to WBNB
 | 
				
			||||||
 | 
					                            // Call `WBNB.deposit{value: sellAmount}()`
 | 
				
			||||||
 | 
					                            mstore(0xB00, WETH_DEPOSIT_CALL_SELECTOR_32)
 | 
				
			||||||
 | 
					                            if iszero(call(gas(), sellToken, sellAmount, 0xB00, 0x4, 0x00, 0x0)) {
 | 
				
			||||||
 | 
					                                bubbleRevert()
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            // Call `WBNB.transfer(pair, sellAmount)`
 | 
				
			||||||
 | 
					                            mstore(0xB00, ERC20_TRANSFER_CALL_SELECTOR_32)
 | 
				
			||||||
 | 
					                            mstore(0xB04, pair)
 | 
				
			||||||
 | 
					                            mstore(0xB24, sellAmount)
 | 
				
			||||||
 | 
					                            if iszero(call(gas(), sellToken, 0, 0xB00, 0x44, 0x00, 0x0)) {
 | 
				
			||||||
 | 
					                                bubbleRevert()
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    // No need to check results, if deposit/transfers failed the PancakeSwapPair will
 | 
				
			||||||
 | 
					                    // reject our trade (or it may succeed if somehow the reserve was out of sync)
 | 
				
			||||||
 | 
					                    // this is fine for the taker.
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Call pair.getReserves(), store the results at `0xC00`
 | 
				
			||||||
 | 
					                mstore(0xB00, PANCAKESWAP_PAIR_RESERVES_CALL_SELECTOR_32)
 | 
				
			||||||
 | 
					                if iszero(staticcall(gas(), pair, 0xB00, 0x4, 0xC00, 0x40)) {
 | 
				
			||||||
 | 
					                    bubbleRevert()
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                // Revert if the pair contract does not return at least two words.
 | 
				
			||||||
 | 
					                if lt(returndatasize(), 0x40) {
 | 
				
			||||||
 | 
					                    mstore(0, pair)
 | 
				
			||||||
 | 
					                    revert(0, 32)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Sell amount for this hop is the previous buy amount.
 | 
				
			||||||
 | 
					                let pairSellAmount := buyAmount
 | 
				
			||||||
 | 
					                // Compute the buy amount based on the pair reserves.
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    let sellReserve
 | 
				
			||||||
 | 
					                    let buyReserve
 | 
				
			||||||
 | 
					                    switch iszero(pairOrder)
 | 
				
			||||||
 | 
					                        case 0 {
 | 
				
			||||||
 | 
					                            // Transpose if pair order is different.
 | 
				
			||||||
 | 
					                            sellReserve := mload(0xC00)
 | 
				
			||||||
 | 
					                            buyReserve := mload(0xC20)
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        default {
 | 
				
			||||||
 | 
					                            sellReserve := mload(0xC20)
 | 
				
			||||||
 | 
					                            buyReserve := mload(0xC00)
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    // Ensure that the sellAmount is < 2¹¹².
 | 
				
			||||||
 | 
					                    if gt(pairSellAmount, MAX_SWAP_AMOUNT) {
 | 
				
			||||||
 | 
					                        revert(0, 0)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    // Pairs are in the range (0, 2¹¹²) so this shouldn't overflow.
 | 
				
			||||||
 | 
					                    // buyAmount = (pairSellAmount * 997 * buyReserve) /
 | 
				
			||||||
 | 
					                    //     (pairSellAmount * 997 + sellReserve * 1000);
 | 
				
			||||||
 | 
					                    let sellAmountWithFee := mul(pairSellAmount, 997)
 | 
				
			||||||
 | 
					                    buyAmount := div(
 | 
				
			||||||
 | 
					                        mul(sellAmountWithFee, buyReserve),
 | 
				
			||||||
 | 
					                        add(sellAmountWithFee, mul(sellReserve, 1000))
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let receiver
 | 
				
			||||||
 | 
					                // Is this the last pair contract?
 | 
				
			||||||
 | 
					                switch eq(add(i, 1), numPairs)
 | 
				
			||||||
 | 
					                    case 0 {
 | 
				
			||||||
 | 
					                        // Not the last pair contract, so forward bought tokens to
 | 
				
			||||||
 | 
					                        // the next pair contract.
 | 
				
			||||||
 | 
					                        nextPair := computePairAddress(
 | 
				
			||||||
 | 
					                            buyToken,
 | 
				
			||||||
 | 
					                            loadTokenAddress(add(i, 2))
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                        receiver := nextPair
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    default {
 | 
				
			||||||
 | 
					                        // The last pair contract.
 | 
				
			||||||
 | 
					                        // Forward directly to taker UNLESS they want BNB back.
 | 
				
			||||||
 | 
					                        switch eq(buyToken, ETH_TOKEN_ADDRESS_32)
 | 
				
			||||||
 | 
					                            case 0 {
 | 
				
			||||||
 | 
					                                receiver := caller()
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            default {
 | 
				
			||||||
 | 
					                                receiver := address()
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Call pair.swap()
 | 
				
			||||||
 | 
					                switch mload(0xA20) // fork
 | 
				
			||||||
 | 
					                    case 2 {
 | 
				
			||||||
 | 
					                        mstore(0xB00, BAKERYSWAP_PAIR_SWAP_CALL_SELECTOR_32)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    default {
 | 
				
			||||||
 | 
					                        mstore(0xB00, PANCAKESWAP_PAIR_SWAP_CALL_SELECTOR_32)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                switch pairOrder
 | 
				
			||||||
 | 
					                    case 0 {
 | 
				
			||||||
 | 
					                        mstore(0xB04, buyAmount)
 | 
				
			||||||
 | 
					                        mstore(0xB24, 0)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    default {
 | 
				
			||||||
 | 
					                        mstore(0xB04, 0)
 | 
				
			||||||
 | 
					                        mstore(0xB24, buyAmount)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                mstore(0xB44, receiver)
 | 
				
			||||||
 | 
					                mstore(0xB64, 0x80)
 | 
				
			||||||
 | 
					                mstore(0xB84, 0)
 | 
				
			||||||
 | 
					                if iszero(call(gas(), pair, 0, 0xB00, 0xA4, 0, 0)) {
 | 
				
			||||||
 | 
					                    bubbleRevert()
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } // End for-loop.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // If buying BNB, unwrap the WBNB first
 | 
				
			||||||
 | 
					            if eq(buyToken, ETH_TOKEN_ADDRESS_32) {
 | 
				
			||||||
 | 
					                // Call `WBNB.withdraw(buyAmount)`
 | 
				
			||||||
 | 
					                mstore(0xB00, WETH_WITHDRAW_CALL_SELECTOR_32)
 | 
				
			||||||
 | 
					                mstore(0xB04, buyAmount)
 | 
				
			||||||
 | 
					                if iszero(call(gas(), mload(0xA40), 0, 0xB00, 0x24, 0x00, 0x0)) {
 | 
				
			||||||
 | 
					                    bubbleRevert()
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                // Transfer BNB to the caller.
 | 
				
			||||||
 | 
					                if iszero(call(gas(), caller(), buyAmount, 0xB00, 0x0, 0x00, 0x0)) {
 | 
				
			||||||
 | 
					                    bubbleRevert()
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Functions ///////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Load a token address from the `tokens` calldata argument.
 | 
				
			||||||
 | 
					            function loadTokenAddress(idx) -> addr {
 | 
				
			||||||
 | 
					                addr := and(ADDRESS_MASK, calldataload(add(mload(0xA00), mul(idx, 0x20))))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Convert BNB pseudo-token addresses to WBNB.
 | 
				
			||||||
 | 
					            function normalizeToken(token) -> normalized {
 | 
				
			||||||
 | 
					                normalized := token
 | 
				
			||||||
 | 
					                // Translate BNB pseudo-tokens to WBNB.
 | 
				
			||||||
 | 
					                if eq(token, ETH_TOKEN_ADDRESS_32) {
 | 
				
			||||||
 | 
					                    normalized := mload(0xA40)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Compute the address of the PancakeSwapPair contract given two
 | 
				
			||||||
 | 
					            // tokens.
 | 
				
			||||||
 | 
					            function computePairAddress(tokenA, tokenB) -> pair {
 | 
				
			||||||
 | 
					                // Convert BNB pseudo-token addresses to WBNB.
 | 
				
			||||||
 | 
					                tokenA := normalizeToken(tokenA)
 | 
				
			||||||
 | 
					                tokenB := normalizeToken(tokenB)
 | 
				
			||||||
 | 
					                // There is one contract for every combination of tokens,
 | 
				
			||||||
 | 
					                // which is deployed using CREATE2.
 | 
				
			||||||
 | 
					                // The derivation of this address is given by:
 | 
				
			||||||
 | 
					                //   address(keccak256(abi.encodePacked(
 | 
				
			||||||
 | 
					                //       bytes(0xFF),
 | 
				
			||||||
 | 
					                //       address(PANCAKESWAP_FACTORY_ADDRESS),
 | 
				
			||||||
 | 
					                //       keccak256(abi.encodePacked(
 | 
				
			||||||
 | 
					                //           tokenA < tokenB ? tokenA : tokenB,
 | 
				
			||||||
 | 
					                //           tokenA < tokenB ? tokenB : tokenA,
 | 
				
			||||||
 | 
					                //       )),
 | 
				
			||||||
 | 
					                //       bytes32(PANCAKESWAP_PAIR_INIT_CODE_HASH),
 | 
				
			||||||
 | 
					                //   )));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Compute the salt (the hash of the sorted tokens).
 | 
				
			||||||
 | 
					                // Tokens are written in reverse memory order to packed encode
 | 
				
			||||||
 | 
					                // them as two 20-byte values in a 40-byte chunk of memory
 | 
				
			||||||
 | 
					                // starting at 0xB0C.
 | 
				
			||||||
 | 
					                switch lt(tokenA, tokenB)
 | 
				
			||||||
 | 
					                    case 0 {
 | 
				
			||||||
 | 
					                        mstore(0xB14, tokenA)
 | 
				
			||||||
 | 
					                        mstore(0xB00, tokenB)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    default {
 | 
				
			||||||
 | 
					                        mstore(0xB14, tokenB)
 | 
				
			||||||
 | 
					                        mstore(0xB00, tokenA)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                let salt := keccak256(0xB0C, 0x28)
 | 
				
			||||||
 | 
					                // Compute the pair address by hashing all the components together.
 | 
				
			||||||
 | 
					                switch mload(0xA20) // fork
 | 
				
			||||||
 | 
					                    case 0 {
 | 
				
			||||||
 | 
					                        mstore(0xB00, FF_PANCAKESWAP_FACTORY)
 | 
				
			||||||
 | 
					                        mstore(0xB15, salt)
 | 
				
			||||||
 | 
					                        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)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    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))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Revert with the return data from the most recent call.
 | 
				
			||||||
 | 
					            function bubbleRevert() {
 | 
				
			||||||
 | 
					                returndatacopy(0, 0, returndatasize())
 | 
				
			||||||
 | 
					                revert(0, returndatasize())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Move `amount` tokens from the taker/caller to `to`.
 | 
				
			||||||
 | 
					            function moveTakerTokensTo(token, to, amount) {
 | 
				
			||||||
 | 
					                // Perform a `transferFrom()`
 | 
				
			||||||
 | 
					                mstore(0xB00, TRANSFER_FROM_CALL_SELECTOR_32)
 | 
				
			||||||
 | 
					                mstore(0xB04, caller())
 | 
				
			||||||
 | 
					                mstore(0xB24, to)
 | 
				
			||||||
 | 
					                mstore(0xB44, amount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let success := call(
 | 
				
			||||||
 | 
					                    gas(),
 | 
				
			||||||
 | 
					                    token,
 | 
				
			||||||
 | 
					                    0,
 | 
				
			||||||
 | 
					                    0xB00,
 | 
				
			||||||
 | 
					                    0x64,
 | 
				
			||||||
 | 
					                    0xC00,
 | 
				
			||||||
 | 
					                    // Copy only the first 32 bytes of return data. We
 | 
				
			||||||
 | 
					                    // only care about reading a boolean in the success
 | 
				
			||||||
 | 
					                    // case. We will use returndatacopy() in the failure case.
 | 
				
			||||||
 | 
					                    0x20
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let rdsize := returndatasize()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Check for ERC20 success. ERC20 tokens should
 | 
				
			||||||
 | 
					                // return a boolean, but some return nothing or
 | 
				
			||||||
 | 
					                // extra data. We accept 0-length return data as
 | 
				
			||||||
 | 
					                // success, or at least 32 bytes that starts with
 | 
				
			||||||
 | 
					                // a 32-byte boolean true.
 | 
				
			||||||
 | 
					                success := and(
 | 
				
			||||||
 | 
					                    success,                         // call itself succeeded
 | 
				
			||||||
 | 
					                    or(
 | 
				
			||||||
 | 
					                        iszero(rdsize),              // no return data, or
 | 
				
			||||||
 | 
					                        and(
 | 
				
			||||||
 | 
					                            iszero(lt(rdsize, 32)),  // at least 32 bytes
 | 
				
			||||||
 | 
					                            eq(mload(0xC00), 1)      // starts with uint256(1)
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if iszero(success) {
 | 
				
			||||||
 | 
					                    // Revert with the data returned from the transferFrom call.
 | 
				
			||||||
 | 
					                    returndatacopy(0, 0, rdsize)
 | 
				
			||||||
 | 
					                    revert(0, rdsize)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Revert if we bought too little.
 | 
				
			||||||
 | 
					        require(buyAmount >= minBuyAmount, "PancakeSwapFeature/UnderBought");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user