Compare commits

...

11 Commits

Author SHA1 Message Date
Savarn Dontamsetti
2851637ee4 DCA Orders 2023-05-25 19:04:22 -04:00
Github Actions
c2aed76f2f Publish
- @0x/contracts-erc20@4.0.8
 - @0x/contracts-test-utils@5.4.54
 - @0x/contracts-treasury@1.4.48
 - @0x/contracts-utils@4.8.46
 - @0x/contracts-zero-ex@0.44.0
 - @0x/contract-addresses@8.7.0
 - @0x/contract-wrappers@13.23.2
 - @0x/protocol-utils@11.22.2
2023-05-10 20:03:48 +00:00
Github Actions
198d986fdc Updated CHANGELOGS & MD docs 2023-05-10 20:03:45 +00:00
Savarn Dontamsetti (Sav)
e2e1d1074c feat: Add TraderJoeV2 MixIn to Arbitrum BridgeAdapter (#723)
* Add TraderJoeV2 MixIn to ArbitrumBridgeAdapter
2023-05-10 15:40:36 -04:00
wonge97
6a15dc3f13 update link (#721) 2023-05-08 17:25:34 -05:00
Github Actions
fefa3c13f6 Publish
- @0x/contracts-erc20@4.0.7
 - @0x/governance@1.0.5
 - @0x/contracts-test-utils@5.4.53
 - @0x/contracts-treasury@1.4.47
 - @0x/contracts-utils@4.8.45
 - @0x/contracts-zero-ex@0.43.0
 - @0x/contract-addresses@8.6.0
 - @0x/contract-wrappers@13.23.1
 - @0x/protocol-utils@11.22.1
2023-05-01 21:25:50 +00:00
Github Actions
f1d096a8af Updated CHANGELOGS & MD docs 2023-05-01 21:25:47 +00:00
Savarn Dontamsetti (Sav)
394ccbdc24 feat: Update Trader Joe V2 MixIn to support V2.1 router (#717)
* Add Trader Joe V2.1 Router MixIn

* Update changelog and FQT address

* lowercasing Avalanche FQT
2023-05-01 15:33:35 -04:00
Savarn Dontamsetti (Sav)
5a47f04ffc fix: remove vm.stopPrank if vm.startPrank not present (#719)
* remove vm.stopPrank if vm.startPrank not present

* remove unnecessary vm.stopPrank from governance tests
2023-05-01 14:13:56 -04:00
wonge97
3c414c12e6 fix malformed table (#718)
table was missing one space :(
2023-04-27 13:19:52 -05:00
wonge97
d268a1136c update bounty page (#716) 2023-04-27 11:51:55 -05:00
49 changed files with 1078 additions and 138 deletions

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1683749017,
"version": "4.0.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1682976338,
"version": "4.0.7",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1681969282,
"version": "4.0.6",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.0.8 - _May 10, 2023_
* Dependencies updated
## v4.0.7 - _May 1, 2023_
* Dependencies updated
## v4.0.6 - _April 20, 2023_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc20",
"version": "4.0.6",
"version": "4.0.8",
"engines": {
"node": ">=6.12"
},
@@ -24,7 +24,7 @@
},
"homepage": "https://github.com/0xProject/protocol",
"devDependencies": {
"@0x/contracts-utils": "^4.8.44",
"@0x/contracts-utils": "^4.8.46",
"@0x/ts-doc-gen": "^0.0.28",
"typedoc": "~0.16.11"
},

View File

@@ -39,7 +39,6 @@ contract WETH9V06Test is Test {
function testShouldConvertDepositedETHToWrappedETH() public {
vm.prank(user);
etherToken.deposit{value: 1e20}();
vm.stopPrank();
assertEq(etherToken.balanceOf(user), 1e20);
assertEq(address(etherToken).balance, 1e20);
@@ -58,7 +57,6 @@ contract WETH9V06Test is Test {
etherToken.deposit{value: 1e20}();
vm.prank(user);
etherToken.withdraw(100);
vm.stopPrank();
assertEq(etherToken.balanceOf(user), 1e20 - 100);
assertEq(address(etherToken).balance, 1e20 - 100);
@@ -68,7 +66,6 @@ contract WETH9V06Test is Test {
function testShouldConvertSentETHToWrappedETH() public {
vm.prank(user);
address(etherToken).call{value: 1e20}(new bytes(0));
vm.stopPrank();
assertEq(etherToken.balanceOf(user), 1e20);
assertEq(address(etherToken).balance, 1e20);

View File

@@ -34,7 +34,6 @@ contract ZRXTokenTest is Test {
assembly {
_address := create(0, add(_bytecode, 0x20), mload(_bytecode))
}
vm.stopPrank();
zrxToken = IERC20Token(address(_address));
}
@@ -73,7 +72,6 @@ contract ZRXTokenTest is Test {
function testShouldReturnFalseIfSenderHasInsufficientBalance() public {
vm.prank(owner);
zrxToken.approve(user, totalSupply + 1);
vm.stopPrank();
bool success = zrxToken.transferFrom(owner, user, totalSupply + 1);
assertEq(success, false);
@@ -82,7 +80,6 @@ contract ZRXTokenTest is Test {
function testShouldReturnFalseIfRecipientHasInsufficientAllowance() public {
vm.prank(owner);
zrxToken.approve(user, totalSupply - 1);
vm.stopPrank();
bool success = zrxToken.transferFrom(owner, user, totalSupply);
assertEq(success, false);
@@ -97,7 +94,6 @@ contract ZRXTokenTest is Test {
function testShouldNotModifySenderAllowanceIfSetToUINT256Max() public {
vm.prank(owner);
zrxToken.approve(user, type(uint256).max);
vm.stopPrank();
zrxToken.transferFrom(owner, user, 100);
assertEq(zrxToken.allowance(owner, user), type(uint256).max);
@@ -106,7 +102,6 @@ contract ZRXTokenTest is Test {
function testShouldTransferCorrectlyWhenSufficientAllowance() public {
vm.prank(owner);
zrxToken.approve(user, 1000 * 1e18);
vm.stopPrank();
vm.prank(user);
zrxToken.transferFrom(owner, user, 100 * 1e18);

View File

@@ -1,4 +1,13 @@
[
{
"timestamp": 1682976338,
"version": "1.0.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1681756154,
"version": "1.0.4",

View File

@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v1.0.5 - _May 1, 2023_
* Dependencies updated
## v1.0.4 - _April 17, 2023_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/governance",
"version": "1.0.4",
"version": "1.0.5",
"description": "Governance implementation for the 0x protocol and treasury",
"main": "index.js",
"directories": {

View File

@@ -90,7 +90,6 @@ abstract contract ZeroExGovernorBaseTest is BaseTest {
// Vote
vm.prank(account2);
governor.castVote(proposalId, 1); // Vote "for"
vm.stopPrank();
// Fast forward to vote end
vm.roll(governor.proposalDeadline(proposalId) + 1);
@@ -155,7 +154,6 @@ abstract contract ZeroExGovernorBaseTest is BaseTest {
// Vote
vm.prank(account2);
governor.castVote(proposalId, 1); // Vote "for"
vm.stopPrank();
// Fast forward to vote end
vm.roll(governor.proposalDeadline(proposalId) + 1);
@@ -266,7 +264,6 @@ abstract contract ZeroExGovernorBaseTest is BaseTest {
// Vote
vm.prank(account2);
governor.castVote(proposalId, 1); // Vote "for"
vm.stopPrank();
// Fast forward to vote end
vm.roll(governor.proposalDeadline(proposalId) + 1);
@@ -330,7 +327,6 @@ abstract contract ZeroExGovernorBaseTest is BaseTest {
// Vote
vm.prank(account2);
governor.castVote(proposalId, 1); // Vote "for"
vm.stopPrank();
// Fast forward to vote end
vm.roll(governor.proposalDeadline(proposalId) + 1);
@@ -366,7 +362,6 @@ abstract contract ZeroExGovernorBaseTest is BaseTest {
// Vote
vm.prank(account2);
governor.castVote(proposalId, 1); // Vote "for"
vm.stopPrank();
// Fast forward to vote end
vm.roll(governor.proposalDeadline(proposalId) + 1);
@@ -402,7 +397,6 @@ abstract contract ZeroExGovernorBaseTest is BaseTest {
// Vote
vm.prank(account2);
governor.castVote(proposalId, 1); // Vote "for"
vm.stopPrank();
// Fast forward to vote end
vm.roll(governor.proposalDeadline(proposalId) + 1);
@@ -438,7 +432,6 @@ abstract contract ZeroExGovernorBaseTest is BaseTest {
// Vote
vm.prank(account2);
governor.castVote(proposalId, 1); // Vote "for"
vm.stopPrank();
// Fast forward to vote end
vm.roll(governor.proposalDeadline(proposalId) + 1);

View File

@@ -70,13 +70,12 @@ contract ZeroExProtocolGovernorTest is ZeroExGovernorBaseTest {
// Vote
vm.prank(account2);
governor.castVote(proposalId, 1); // Vote "for"
vm.stopPrank();
vm.prank(account3);
governor.castVote(proposalId, 0); // Vote "against"
vm.stopPrank();
vm.prank(account4);
governor.castVote(proposalId, 2); // Vote "abstain"
vm.stopPrank();
// Fast forward to vote end
vm.roll(governor.proposalDeadline(proposalId) + 1);

View File

@@ -66,13 +66,12 @@ contract ZeroExTreasuryGovernorTest is ZeroExGovernorBaseTest {
// Vote
vm.prank(account2);
governor.castVote(proposalId, 1); // Vote "for"
vm.stopPrank();
vm.prank(account3);
governor.castVote(proposalId, 0); // Vote "against"
vm.stopPrank();
vm.prank(account4);
governor.castVote(proposalId, 2); // Vote "abstain"
vm.stopPrank();
// Fast forward to vote end
vm.roll(governor.proposalDeadline(proposalId) + 1);

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1683749017,
"version": "5.4.54",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1682976338,
"version": "5.4.53",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1681969282,
"version": "5.4.52",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v5.4.54 - _May 10, 2023_
* Dependencies updated
## v5.4.53 - _May 1, 2023_
* Dependencies updated
## v5.4.52 - _April 20, 2023_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-test-utils",
"version": "5.4.52",
"version": "5.4.54",
"engines": {
"node": ">=6.12"
},
@@ -41,7 +41,7 @@
"dependencies": {
"@0x/assert": "^3.0.36",
"@0x/base-contract": "^7.0.0",
"@0x/contract-addresses": "^8.5.0",
"@0x/contract-addresses": "^8.7.0",
"@0x/dev-utils": "^5.0.2",
"@0x/json-schemas": "^6.4.4",
"@0x/order-utils": "^10.4.28",

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1683749017,
"version": "1.4.48",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1682976338,
"version": "1.4.47",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1682334742,
"version": "1.4.46",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v1.4.48 - _May 10, 2023_
* Dependencies updated
## v1.4.47 - _May 1, 2023_
* Dependencies updated
## v1.4.46 - _April 24, 2023_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-treasury",
"version": "1.4.46",
"version": "1.4.48",
"engines": {
"node": ">=6.12"
},
@@ -46,12 +46,12 @@
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury",
"devDependencies": {
"@0x/abi-gen": "^5.8.5",
"@0x/contract-addresses": "^8.5.0",
"@0x/contract-addresses": "^8.7.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-erc20": "3.3.57",
"@0x/contracts-gen": "^2.0.50",
"@0x/contracts-staking": "^2.0.45",
"@0x/contracts-test-utils": "^5.4.52",
"@0x/contracts-test-utils": "^5.4.54",
"@0x/sol-compiler": "^4.8.2",
"@0x/ts-doc-gen": "^0.0.28",
"@types/isomorphic-fetch": "^0.0.35",
@@ -73,7 +73,7 @@
},
"dependencies": {
"@0x/base-contract": "^7.0.0",
"@0x/protocol-utils": "^11.22.0",
"@0x/protocol-utils": "^11.22.2",
"@0x/subproviders": "^8.0.1",
"@0x/types": "^3.3.7",
"@0x/typescript-typings": "^5.3.1",

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1683749017,
"version": "4.8.46",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1682976338,
"version": "4.8.45",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1681969282,
"version": "4.8.44",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.8.46 - _May 10, 2023_
* Dependencies updated
## v4.8.45 - _May 1, 2023_
* Dependencies updated
## v4.8.44 - _April 20, 2023_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-utils",
"version": "4.8.44",
"version": "4.8.46",
"engines": {
"node": ">=6.12"
},
@@ -45,7 +45,7 @@
"devDependencies": {
"@0x/abi-gen": "^5.8.5",
"@0x/contracts-gen": "^2.0.50",
"@0x/contracts-test-utils": "^5.4.52",
"@0x/contracts-test-utils": "^5.4.54",
"@0x/dev-utils": "^5.0.2",
"@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.8.2",

View File

@@ -1,4 +1,22 @@
[
{
"version": "0.44.0",
"changes": [
{
"note": "Add Trader Joe V2 MixIn to Arbitrum"
}
],
"timestamp": 1683749017
},
{
"version": "0.43.0",
"changes": [
{
"note": "Add Trader Joe V2.1 Router Support for MixIn"
}
],
"timestamp": 1682976338
},
{
"timestamp": 1682334742,
"version": "0.42.1",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.44.0 - _May 10, 2023_
* Add Trader Joe V2 MixIn to Arbitrum
## v0.43.0 - _May 1, 2023_
* Add Trader Joe V2.1 Router Support for MixIn
## v0.42.1 - _April 24, 2023_
* Dependencies updated

View File

@@ -0,0 +1,36 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2023 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;
pragma experimental ABIEncoderV2;
import "forge-std/Test.sol";
import "forge-std/Script.sol";
import "@0x/contracts-erc20/src/IERC20Token.sol";
contract DealMe is Test, Script {
function setUp() public {}
function run() public {
// set approval
vm.startBroadcast(0x6879fAb591ed0d62537A3Cac9D7cd41218445a84);
IERC20Token(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48).approve(
0xDef1C0ded9bec7F1a1670819833240f027b25EfF,
type(uint256).max
);
vm.stopBroadcast();
}
}

View File

@@ -0,0 +1,38 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2023 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;
pragma experimental ABIEncoderV2;
import "forge-std/Test.sol";
import "forge-std/Script.sol";
import "@0x/contracts-erc20/src/IERC20Token.sol";
contract DealMe is Test, Script {
function setUp() public {}
function run() public {
vm.startBroadcast(0x47ac0Fb4F2D84898e4D9E7b4DaB3C24507a6D503);
IERC20Token(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48).transfer(
0x6879fAb591ed0d62537A3Cac9D7cd41218445a84,
1000e6
);
(0x6879fAb591ed0d62537A3Cac9D7cd41218445a84).transfer(1 ether);
(0xb985d345c4bb8121cE2d18583b2a28e98D56d04b).transfer(1 ether);
vm.stopBroadcast();
}
}

View File

@@ -0,0 +1,83 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2023 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;
pragma experimental ABIEncoderV2;
import "../utils/ForkUtils.sol";
import "../utils/TestUtils.sol";
import "src/IZeroEx.sol";
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "src/features/TransformERC20Feature.sol";
import "src/external/TransformerDeployer.sol";
import "src/transformers/WethTransformer.sol";
import "src/transformers/FillQuoteTransformer.sol";
import "src/transformers/bridges/BridgeProtocols.sol";
import "src/features/OtcOrdersFeature.sol";
contract TraceCalldata is Test, ForkUtils, TestUtils {
using LibERC20TokenV06 for IERC20TokenV06;
function setUp() public {
_setup();
}
function test_traceZeroExCall() public {
log_string("TraceExchangeProxyCall");
for (uint256 i = 0; i < 1; i++) {
//skip fantom/avax failing test
if (i == 3 || i == 4) {
continue;
}
vm.selectFork(forkIds[chains[i]]);
log_named_string(" Selecting Fork On", chains[i]);
vm.deal(address(this), 1e18);
labelAddresses(
chains[i],
indexChainsByChain[chains[i]],
getTokens(i),
getContractAddresses(i),
getLiquiditySourceAddresses(i)
);
swapWithOtcOrder(getTokens(i), getContractAddresses(i), getLiquiditySourceAddresses(i));
}
}
/* solhint-disable function-max-lines */
function swapWithOtcOrder(
TokenAddresses memory tokens,
ContractAddresses memory addresses,
LiquiditySources memory sources
) public onlyForked {
IZERO_EX = IZeroEx(addresses.exchangeProxy);
address taker = address(0xd00d00cAca000000000000000000000000001337);
vm.label(taker, "API Quote Taker");
deal(address(tokens.USDT), taker, 100e30);
//deal(address(tokens.WrappedNativeToken), taker, 100e30);
vm.startPrank(taker);
IERC20TokenV06(tokens.USDT).approveIfBelow(address(addresses.exchangeProxy), uint256(-1));
//IERC20TokenV06(tokens.WrappedNativeToken).approveIfBelow(address(taker), uint256(-1));
//emit log_address(address(tokens.WrappedNativeToken));
IERC20TokenV06(tokens.USDT).balanceOf(taker);
IERC20TokenV06(tokens.WrappedNativeToken).balanceOf(taker);
(bool success, bytes memory result) = addresses.exchangeProxy.call(
hex"7a1eb1b9000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000003dd141a0000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000180000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000003e711b8000000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000a3f14cb81e6edb7b1249755dd20e2bfb23597fd70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d00d00caca0000000000000000000000000013370000000063f50e17000000000000000200000000000000000000000063f50da10000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001c543148f2a2124e690f19ab0042906b437f954a52b9fbef6019c3968befac860466a819bd38bb6c60c5341f65d3e596d17573c80fc78a3a837d7ed6392b66e783000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000003e711b80000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000180000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000003e6b1b23900000000000000000000000000000000000000000000000000000003e711b800000000000000000000000000af0b0000f0210d0f421f0009c72406703b50506b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d00d00caca0000000000000000000000000013370000000063f50dfb000000000000001f00000000000000000000000063f50da20000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001beb5fbe9aa7694028216b8d81e613a41a9cf8b9135729d33acf77a692c4b0123547884cb6bae49c9ac885204ae11ce6fd4fff3961c04be142933b0c1b2e99072d869584cd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007ebba8e3ba63f50e10"
);
emit log_named_bytes("", result);
vm.stopPrank();
}
}

View File

@@ -0,0 +1,39 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2023 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;
pragma experimental ABIEncoderV2;
import "forge-std/Test.sol";
import "forge-std/Script.sol";
import "src/features/DCAFeature.sol";
import "src/IZeroEx.sol";
import "src/ZeroEx.sol";
contract DeployDCAFeature is Test, Script {
ZeroEx public ZERO_EX = ZeroEx(0xDef1C0ded9bec7F1a1670819833240f027b25EfF);
IZeroEx public IZERO_EX = IZeroEx(address(ZERO_EX));
function setUp() public {}
function run() public {
vm.startBroadcast(IZERO_EX.owner());
DCAFeature feature = new DCAFeature(address(ZERO_EX));
IZERO_EX.migrate(address(feature), abi.encodeWithSelector(DCAFeature.migrate.selector), IZERO_EX.owner());
vm.stopBroadcast();
}
}

View File

@@ -0,0 +1,68 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2023 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;
pragma experimental ABIEncoderV2;
import "forge-std/Test.sol";
import "forge-std/Script.sol";
import "src/features/DCAFeature.sol";
import "src/features/interfaces/IDCAFeature.sol";
import "src/IZeroEx.sol";
import "src/ZeroEx.sol";
contract TestDeploy is Test, Script {
ZeroEx public ZERO_EX = ZeroEx(0xDef1C0ded9bec7F1a1670819833240f027b25EfF);
IZeroEx public IZERO_EX = IZeroEx(address(ZERO_EX));
function setUp() public {}
function run() public {
uint256 signerPrivateKey = 0xA11CE;
address signer = vm.addr(signerPrivateKey);
IDCAFeature.DCAData memory dcaData = IDCAFeature.DCAData({
buyToken: IERC20Token(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2),
sellToken: IERC20Token(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48),
sellAmount: 100,
interval: 600,
numFills: 12,
startTime: block.timestamp,
signer: payable(signer)
});
bytes32 dcahash = IDCAFeature(address(ZERO_EX)).getDCAHash(dcaData);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKey, dcahash);
LibSignature.Signature memory signature = LibSignature.Signature({
signatureType: LibSignature.SignatureType.EIP712,
v: v,
r: r,
s: s
});
ITransformERC20Feature.Transformation[] memory transformations = new ITransformERC20Feature.Transformation[](0);
bytes memory swapCalldata = abi.encodeWithSelector(
IZERO_EX.transformERC20.selector,
dcaData.sellToken,
dcaData.buyToken,
1e18,
1e18,
transformations
);
IDCAFeature(address(ZERO_EX)).fillDCATransaction(dcaData, signature, swapCalldata);
}
}

View File

@@ -0,0 +1,284 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2023 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/LibBytesV06.sol";
import "../fixins/FixinCommon.sol";
import "../fixins/FixinEIP712.sol";
import "./interfaces/IFeature.sol";
import "./interfaces/IDCAFeature.sol";
import "./libs/LibSignature.sol";
import "../migrations/LibMigrate.sol";
import "./interfaces/ITransformERC20Feature.sol";
import "forge-std/Test.sol";
/// @dev DCA feature.
contract DCAFeature is IFeature, IDCAFeature, FixinCommon, FixinEIP712 {
using LibBytesV06 for bytes;
using LibRichErrorsV06 for bytes;
/// @dev Describes the state of the DCA.
struct ExecuteState {
// Hash of the DCA order.
bytes32 hash;
// The DCA order data;
DCAData dca;
// The DCA signature (by `dca.signer`).
LibSignature.Signature signature;
// The calldata to fill for the current iteration of the DCA.
bytes swapCalldata;
}
/// @dev Arguments for a `TransformERC20.transformERC20()` call.
struct ExternalTransformERC20Args {
IERC20Token inputToken;
IERC20Token outputToken;
uint256 inputTokenAmount;
uint256 minOutputTokenAmount;
ITransformERC20Feature.Transformation[] transformations;
}
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "DCA";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
/// @dev EIP712 typehash of the `DCAData` struct.
bytes32 public constant DCA_DATA_TYPEHASH =
keccak256(
"DCAData("
"address buyToken,"
"address sellToken,"
"uint256 sellAmount,"
"uint256 interval,"
"uint256 numFills,"
"uint256 startTime,"
"address signer"
")"
);
/// @dev number of fills executed per DCA order.
mapping(bytes32 => uint256) public numFilled;
constructor(address zeroExAddress) public FixinCommon() FixinEIP712(zeroExAddress) {}
function migrate() external returns (bytes4 success) {
_registerFeatureFunction(this.fillDCATransaction.selector);
_registerFeatureFunction(this.getDCAHash.selector);
return LibMigrate.MIGRATE_SUCCESS;
}
function fillDCATransaction(
DCAData calldata dcaData,
LibSignature.Signature calldata signature,
bytes calldata swapCallData
) public override returns (bytes memory returnResult) {
ExecuteState memory state;
state.dca = dcaData;
state.hash = getDCAHash(dcaData);
state.signature = signature;
state.swapCalldata = swapCallData;
returnResult = _fillDCATransaction(state);
}
/// @dev Get the EIP712 hash of a dca order.
/// @param dca The DCA order.
/// @return dcaHash the EIP712 hash of 'dca'.
function getDCAHash(DCAData memory dca) public view override returns (bytes32 dcaHash) {
return
_getEIP712Hash(
keccak256(
abi.encode(
DCA_DATA_TYPEHASH,
dca.buyToken,
dca.sellToken,
dca.sellAmount,
dca.interval,
dca.numFills,
dca.startTime,
dca.signer
)
)
);
}
function _fillDCATransaction(ExecuteState memory state) private returns (bytes memory returnResult) {
_validateDCATransaction(state);
// get balances of sellToken and buyToken before we execute calldata
uint256 sellTokenBalanceBefore = state.dca.sellToken.balanceOf(state.dca.signer);
uint256 buyTokenBalanceBefore = state.dca.buyToken.balanceOf(state.dca.signer);
// execute the calldata
bytes4 selector = state.swapCalldata.readBytes4(0);
if (selector == ITransformERC20Feature.transformERC20.selector) {
returnResult = _executeTransformERC20Call(state);
} else {
revert("Unsupported swap function");
}
// get the balances of the sellToken and buyToken after we execute the calldata
uint256 sellTokenBalanceAfter = state.dca.sellToken.balanceOf(state.dca.signer);
uint256 buyTokenBalanceAfter = state.dca.buyToken.balanceOf(state.dca.signer);
// validate deltas
if (sellTokenBalanceAfter > sellTokenBalanceBefore) {
revert("Sell token balance increased");
}
if (sellTokenBalanceBefore - sellTokenBalanceAfter != state.dca.sellAmount) {
revert("Sell token balance delta does not match sell amount");
}
if (buyTokenBalanceAfter < buyTokenBalanceBefore) {
revert("Buy token balance decreased");
}
// TODO query oracle to ensure minslippage is achieved
// update storage to show that we have executed the order
numFilled[state.hash] += 1;
}
function _validateDCATransaction(ExecuteState memory state) private view {
// validate that the signature
if (LibSignature.getSignerOfHash(state.hash, state.signature) != state.dca.signer) {
LibSignatureRichErrors
.SignatureValidationError(
LibSignatureRichErrors.SignatureValidationErrorCodes.WRONG_SIGNER,
state.hash,
state.dca.signer,
// TODO: Remove this field from SignatureValidationError
// when rich reverts are part of the protocol repo.
""
)
.rrevert();
}
// check if all DCA orders have been executed already
if (numFilled[state.hash] == state.dca.numFills) {
revert("All DCA orders have been executed already");
}
// Check that DCA order is within the right time window
uint256 endTime = state.dca.startTime + (state.dca.interval * state.dca.numFills);
if (block.timestamp < state.dca.startTime || block.timestamp > endTime) {
revert("Invalid time window");
}
uint256 currTime = block.timestamp;
uint256 currFill = (state.dca.numFills * (currTime - state.dca.startTime)) / (endTime - state.dca.startTime); // zero-indexed
uint256 currWindowMidpoint = ((currFill + 1) * (endTime - state.dca.startTime)) / state.dca.numFills;
currWindowMidpoint = currWindowMidpoint + state.dca.startTime;
uint256 halfWindowSizeSeconds = 150; // 2.5 minutes
uint256 currWindowStart = currWindowMidpoint < halfWindowSizeSeconds
? 0
: currWindowMidpoint - halfWindowSizeSeconds;
uint256 currWindowEnd = currWindowMidpoint + halfWindowSizeSeconds;
if (currTime < currWindowStart || currTime > currWindowEnd) {
console.log(
"currTime=%d, currWindowMidpoint=%d, halfWindow=%d",
currTime,
currWindowMidpoint,
halfWindowSizeSeconds
);
revert("Invalid time window 2");
}
}
/// @dev Execute a `ITransformERC20Feature.transformERC20()` meta-transaction call
/// by decoding the call args and translating the call to the internal
/// `ITransformERC20Feature._transformERC20()` variant, where we can override
/// the taker address.
function _executeTransformERC20Call(ExecuteState memory state) private returns (bytes memory returnResult) {
// HACK(dorothy-zbornak): `abi.decode()` with the individual args
// will cause a stack overflow. But we can prefix the call data with an
// offset to transform it into the encoding for the equivalent single struct arg,
// since decoding a single struct arg consumes far less stack space than
// decoding multiple struct args.
// Where the encoding for multiple args (with the selector ommitted)
// would typically look like:
// | argument | offset |
// |--------------------------|---------|
// | inputToken | 0 |
// | outputToken | 32 |
// | inputTokenAmount | 64 |
// | minOutputTokenAmount | 96 |
// | transformations (offset) | 128 | = 32
// | transformations (data) | 160 |
// We will ABI-decode a single struct arg copy with the layout:
// | argument | offset |
// |--------------------------|---------|
// | (arg 1 offset) | 0 | = 32
// | inputToken | 32 |
// | outputToken | 64 |
// | inputTokenAmount | 96 |
// | minOutputTokenAmount | 128 |
// | transformations (offset) | 160 | = 32
// | transformations (data) | 192 |
ExternalTransformERC20Args memory args;
{
bytes memory encodedStructArgs = new bytes(state.swapCalldata.length - 4 + 32);
// Copy the args data from the original, after the new struct offset prefix.
bytes memory fromCallData = state.swapCalldata;
assert(fromCallData.length >= 160);
uint256 fromMem;
uint256 toMem;
assembly {
// Prefix the calldata with a struct offset,
// which points to just one word over.
mstore(add(encodedStructArgs, 32), 32)
// Copy everything after the selector.
fromMem := add(fromCallData, 36)
// Start copying after the struct offset.
toMem := add(encodedStructArgs, 64)
}
LibBytesV06.memCopy(toMem, fromMem, fromCallData.length - 4);
// Decode call args for `ITransformERC20Feature.transformERC20()` as a struct.
args = abi.decode(encodedStructArgs, (ExternalTransformERC20Args));
}
// Call `ITransformERC20Feature._transformERC20()` (internal variant).
return
_callSelf(
abi.encodeWithSelector(
ITransformERC20Feature._transformERC20.selector,
ITransformERC20Feature.TransformERC20Args({
taker: state.dca.signer, // taker is mtx signer
inputToken: args.inputToken,
outputToken: args.outputToken,
inputTokenAmount: args.inputTokenAmount,
minOutputTokenAmount: args.minOutputTokenAmount,
transformations: args.transformations,
useSelfBalance: false,
recipient: state.dca.signer
})
)
);
}
/// @dev Make an arbitrary internal, meta-transaction call.
/// Warning: Do not let unadulterated `callData` into this function.
function _callSelf(bytes memory callData) private returns (bytes memory returnResult) {
bool success;
(success, returnResult) = address(this).call(callData);
if (!success) {
console.logBytes(returnResult);
revert("Swap execution failed ");
}
}
}

View File

@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2023 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/src/IERC20Token.sol";
import "../libs/LibSignature.sol";
/// @dev DCA feature.
interface IDCAFeature {
struct DCAData {
// The token to buy.
IERC20Token buyToken;
// The token to sell.
IERC20Token sellToken;
// The amount of sellToken to sell.
uint256 sellAmount;
// The amount of time between each fill in seconds.
uint256 interval;
// The number of fills to execute.
uint256 numFills;
// The start time of the DCA order in Unix epoch seconds.
uint256 startTime;
// Signer of the DCA. On whose behalf to execute the DCA.
address payable signer;
}
function fillDCATransaction(
DCAData calldata dcaData,
LibSignature.Signature calldata signature,
bytes calldata swapCallData
) external returns (bytes memory returnResult);
function getDCAHash(DCAData calldata dcaData) external view returns (bytes32 dcaHash);
}

View File

@@ -26,6 +26,7 @@ import "./mixins/MixinKyberDmm.sol";
import "./mixins/MixinKyberElastic.sol";
import "./mixins/MixinGMX.sol";
import "./mixins/MixinNerve.sol";
import "./mixins/MixinTraderJoeV2.sol";
import "./mixins/MixinUniswapV3.sol";
import "./mixins/MixinUniswapV2.sol";
import "./mixins/MixinWOOFi.sol";
@@ -42,6 +43,7 @@ contract ArbitrumBridgeAdapter is
MixinKyberElastic,
MixinGMX,
MixinNerve,
MixinTraderJoeV2,
MixinUniswapV3,
MixinUniswapV2,
MixinWOOFi,
@@ -97,6 +99,11 @@ contract ArbitrumBridgeAdapter is
return (0, true);
}
boughtAmount = _tradeUniswapV2(buyToken, sellAmount, order.bridgeData);
} else if (protocolId == BridgeProtocols.TRADERJOEV2) {
if (dryRun) {
return (0, true);
}
boughtAmount = _tradeTraderJoeV2(buyToken, sellAmount, order.bridgeData);
} else if (protocolId == BridgeProtocols.GMX) {
if (dryRun) {
return (0, true);

View File

@@ -20,19 +20,43 @@ import "@0x/contracts-erc20/src/IERC20Token.sol";
import "../IBridgeAdapter.sol";
interface ILBRouter {
/// @notice Swaps exact tokens for tokens while performing safety checks
/// @param amountIn The amount of token to send
/// @param amountOutMin The min amount of token to receive
/// @param pairBinSteps The bin step of the pairs (0: V1, other values will use V2)
/// @param tokenPath The swap path using the binSteps following `_pairBinSteps`
/// @param to The address of the recipient
/// @param deadline The deadline of the tx
/// @return amountOut Output amount of the swap
/**
* @dev This enum represents the version of the pair requested
* - V1: Joe V1 pair
* - V2: LB pair V2. Also called legacyPair
* - V2_1: LB pair V2.1 (current version)
*/
enum Version {
V1,
V2,
V2_1
}
/**
* @dev The path parameters, such as:
* - pairBinSteps: The list of bin steps of the pairs to go through
* - versions: The list of versions of the pairs to go through
* - tokenPath: The list of tokens in the path to go through
*/
struct Path {
uint256[] pairBinSteps;
Version[] versions;
IERC20Token[] tokenPath;
}
/**
* @notice Swaps exact tokens for tokens while performing safety checks
* @param amountIn The amount of token to send
* @param amountOutMin The min amount of token to receive
* @param path The path of the swap
* @param to The address of the recipient
* @param deadline The deadline of the tx
* @return amountOut Output amount of the swap
*/
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
uint256[] memory pairBinSteps,
IERC20Token[] memory tokenPath,
Path memory path,
address to,
uint256 deadline
) external returns (uint256 amountOut);
@@ -49,12 +73,16 @@ contract MixinTraderJoeV2 {
ILBRouter router;
IERC20Token[] memory tokenPath;
uint256[] memory pairBinSteps;
ILBRouter.Version[] memory versions;
{
address[] memory _path;
(router, _path, pairBinSteps) = abi.decode(bridgeData, (ILBRouter, address[], uint256[]));
address[] memory _tokenPath;
(router, _tokenPath, pairBinSteps, versions) = abi.decode(
bridgeData,
(ILBRouter, address[], uint256[], ILBRouter.Version[])
);
// To get around `abi.decode()` not supporting interface array types.
assembly {
tokenPath := _path
tokenPath := _tokenPath
}
}
@@ -63,6 +91,10 @@ contract MixinTraderJoeV2 {
tokenPath.length == pairBinSteps.length + 1,
"MixinTraderJoeV2/PAIR_BIN_STEPS_LENGTH_MUST_BE_ONE_LESS_THAN_TOKEN_PATH_LENGTH"
);
require(
versions.length == pairBinSteps.length,
"MixinTraderJoeV2/VERSIONS_LENGTH_MUST_BE_EQUAL_TO_PAIR_BIN_STEPS_LENGTH"
);
require(
tokenPath[tokenPath.length - 1] == buyToken,
"MixinTraderJoeV2/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
@@ -70,13 +102,11 @@ contract MixinTraderJoeV2 {
// Grant the Trader Joe V2 router an allowance to sell the first token.
tokenPath[0].approveIfBelow(address(router), sellAmount);
boughtAmount = router.swapExactTokensForTokens(
sellAmount,
1,
pairBinSteps,
tokenPath,
address(this),
block.timestamp
);
ILBRouter.Path memory path = ILBRouter.Path({
pairBinSteps: pairBinSteps,
versions: versions,
tokenPath: tokenPath
});
boughtAmount = router.swapExactTokensForTokens(sellAmount, 1, path, address(this), block.timestamp);
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-zero-ex",
"version": "0.42.1",
"version": "0.44.0",
"engines": {
"node": ">=6.12"
},
@@ -51,10 +51,10 @@
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex",
"devDependencies": {
"@0x/abi-gen": "^5.8.5",
"@0x/contract-addresses": "^8.5.0",
"@0x/contract-addresses": "^8.7.0",
"@0x/contracts-erc20": "^3.3.57",
"@0x/contracts-gen": "^2.0.50",
"@0x/contracts-test-utils": "^5.4.52",
"@0x/contracts-test-utils": "^5.4.54",
"@0x/dev-utils": "^5.0.2",
"@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.8.2",
@@ -80,7 +80,7 @@
},
"dependencies": {
"@0x/base-contract": "^7.0.0",
"@0x/protocol-utils": "^11.22.0",
"@0x/protocol-utils": "^11.22.2",
"@0x/subproviders": "^8.0.1",
"@0x/types": "^3.3.7",
"@0x/typescript-typings": "^5.3.1",

View File

@@ -0,0 +1,115 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2023 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 "forge-std/Test.sol";
import "forge-std/StdUtils.sol";
import "./utils/LocalTest.sol";
import "../contracts/src/features/DCAFeature.sol";
import "../contracts/src/features/interfaces/IDCAFeature.sol";
import "@0x/contracts-erc20/src/IERC20Token.sol";
import "../contracts/src/fixins/FixinEIP712.sol";
import "../contracts/src/features/libs/LibSignature.sol";
contract DCAFeatureTest is LocalTest {
function test_validateSignature() public {
uint256 signerPrivateKey = 0xA11CE;
address signer = vm.addr(signerPrivateKey);
IDCAFeature.DCAData memory dcaData = IDCAFeature.DCAData({
buyToken: IERC20Token(address(0)),
sellToken: IERC20Token(address(0)),
sellAmount: 100,
interval: 100,
numFills: 8,
startTime: block.timestamp,
signer: payable(signer)
});
bytes32 dcaHash = zeroExDeployed.features.dcaFeature.getDCAHash(dcaData);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKey, dcaHash);
LibSignature.Signature memory signature = LibSignature.Signature({
signatureType: LibSignature.SignatureType.EIP712,
v: v,
r: r,
s: s
});
assertEq(LibSignature.getSignerOfHash(dcaHash, signature), dcaData.signer);
}
function test_checkNumFilled() public {
// check that if user signed order to execute order two times, we expect
// a revert on the third try
}
function test_timeWindow() public {
// spoof the blockchain timestmap and expect a revert if we're outside
}
function test_dcaSwap() public {
uint256 signerPrivateKey = 0xA11CE;
address signer = vm.addr(signerPrivateKey);
IDCAFeature.DCAData memory dcaData = IDCAFeature.DCAData({
// buyToken: IERC20Token(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2),
// sellToken: IERC20Token(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48),
buyToken: zrx,
sellToken: dai,
sellAmount: 100,
interval: 600,
numFills: 12,
startTime: block.timestamp,
signer: payable(signer)
});
vm.warp(600); // warp the blockchain 10 minutes into the future
bytes32 dcaHash = zeroExDeployed.features.dcaFeature.getDCAHash(dcaData);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKey, dcaHash);
LibSignature.Signature memory signature = LibSignature.Signature({
signatureType: LibSignature.SignatureType.EIP712,
v: v,
r: r,
s: s
});
ITransformERC20Feature.Transformation[] memory transformations = new ITransformERC20Feature.Transformation[](1);
transformations[0] = ITransformERC20Feature.Transformation(
uint32(transformerNonce),
abi.encode(address(dcaData.sellToken), address(dcaData.buyToken), 0, 1e18, 0)
);
console.log(transformerNonce);
_mintTo(address(dcaData.sellToken), signer, 1e18);
vm.prank(signer);
dcaData.sellToken.approve(address(zeroExDeployed.zeroEx), 1e18);
bytes memory swapCalldata = abi.encodeWithSelector(
zeroExDeployed.zeroEx.transformERC20.selector,
dcaData.sellToken,
dcaData.buyToken,
1e18,
1e18,
transformations
);
assertEq(dai.balanceOf(signer), 1e18);
IDCAFeature(address(zeroExDeployed.zeroEx)).fillDCATransaction(dcaData, signature, swapCalldata);
}
}

View File

@@ -5,7 +5,7 @@
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
"KyberElasticPool": "0x952ffc4c47d66b454a8181f5c68b6248e18b66ec",
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Quoter": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
},
"56": {
@@ -14,7 +14,7 @@
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
"KyberElasticPool": "0xfbfab68ba077d099cd4b66fa76920572cc0b557c",
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Quoter": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
},
"137": {
@@ -23,7 +23,7 @@
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
"KyberElasticPool": "0xf9cc934753a127100585812181ac04d07158a4c2",
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Quoter": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
},
"43114": {
@@ -32,8 +32,8 @@
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
"KyberElasticPool": "0x6038373de7f64da99b2a31951628b7d778b2c3cf",
"TraderJoeV2Pool": "0x1D7A1a79e2b4Ef88D2323f3845246D24a3c20F1d",
"TraderJoeV2Router": "0xE3Ffc583dC176575eEA7FD9dF2A7c65F7E23f4C3"
"TraderJoeV2Quoter": "0x64b57F4249aA99a812212cee7DAEFEDC40B203cD",
"TraderJoeV2Router": "0xb4315e873dBcf96Ffd0acd8EA43f689D8c20fB30"
},
"250": {
"UniswapV2Router": "0x1b02da8cb0d097eb8d57a175b88c7d8b47997506",
@@ -41,7 +41,7 @@
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
"KyberElasticPool": "0x8dcf5fed6ae6bf0befb5e4f0c9414c2cb9a4ed01",
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Quoter": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
},
"10": {
@@ -50,7 +50,7 @@
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
"KyberElasticPool": "0x7e29ccaa4bf2894aca02c77e6b99cafc1d24b2f5",
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Quoter": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
},
"42161": {
@@ -59,7 +59,7 @@
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
"KyberElasticPool": "0x087abaab9cd85025a8b3916948c69fe173c837ea",
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
"TraderJoeV2Quoter": "0x64b57F4249aA99a812212cee7DAEFEDC40B203cD",
"TraderJoeV2Router": "0xb4315e873dBcf96Ffd0acd8EA43f689D8c20fB30"
}
}

View File

@@ -56,8 +56,8 @@ contract SwapERC20ForERC20Test is Test, ForkUtils, TestUtils {
function test_swapERC20ForERC20OnTraderJoeV2() public {
for (uint256 i = 0; i < chains.length; i++) {
// TraderJoeV2 mixin only enabled on Avalanche
if (i != 3) {
// TraderJoeV2 mixin only enabled on Avalanche and Arbitrum
if (i != 3 && i != 6) {
continue;
}
vm.selectFork(forkIds[chains[i]]);
@@ -81,8 +81,8 @@ contract SwapERC20ForERC20Test is Test, ForkUtils, TestUtils {
emit log_string("TraderJoeV2Router not available on this chain");
return;
}
if (sources.TraderJoeV2Pool == address(0)) {
emit log_string("TraderJoeV2Pool not available on this chain");
if (sources.TraderJoeV2Quoter == address(0)) {
emit log_string("TraderJoeV2Quoter not available on this chain");
return;
}
@@ -94,12 +94,11 @@ contract SwapERC20ForERC20Test is Test, ForkUtils, TestUtils {
fqtData.fillSequence[0] = FillQuoteTransformer.OrderType.Bridge;
fqtData.fillAmount = 1e6;
(uint256 amountOut, uint256 binStep) = sampleTraderJoeV2(
(uint256 amountOut, uint256 binStep, uint256 version) = sampleTraderJoeV2(
fqtData.fillAmount,
address(fqtData.sellToken),
address(fqtData.buyToken),
sources.TraderJoeV2Router,
sources.TraderJoeV2Pool
sources.TraderJoeV2Quoter
);
log_named_uint("amountOut", amountOut);
@@ -110,7 +109,9 @@ contract SwapERC20ForERC20Test is Test, ForkUtils, TestUtils {
tokenPath[1] = address(fqtData.buyToken);
uint256[] memory binSteps = new uint256[](1);
binSteps[0] = binStep;
order.bridgeData = abi.encode(address(sources.TraderJoeV2Router), tokenPath, binSteps);
uint256[] memory versions = new uint256[](1);
versions[0] = version;
order.bridgeData = abi.encode(address(sources.TraderJoeV2Router), tokenPath, binSteps, versions);
}
order.source = bytes32(uint256(BridgeProtocols.TRADERJOEV2) << 128);
@@ -198,20 +199,23 @@ contract SwapERC20ForERC20Test is Test, ForkUtils, TestUtils {
uint256 amount,
address takerToken,
address makerToken,
address router,
address pool
) private returns (uint256 makerTokenAmount, uint256 binStep) {
address quoter
) private returns (uint256 makerTokenAmount, uint256 binStep, uint256 version) {
log_string("Sampling TraderJoeV2");
log_named_address("takerToken", takerToken);
log_named_address("makerToken", makerToken);
log_named_address("router", router);
log_named_address("pool", pool);
log_named_address("quoter", quoter);
bool swapForY = ITraderJoeV2Pool(pool).tokenY() == makerToken;
address[] memory tokenPath = new address[](2);
tokenPath[0] = takerToken;
tokenPath[1] = makerToken;
(makerTokenAmount, ) = ITraderJoeV2Router(router).getSwapOut(pool, amount, swapForY);
ITraderJoeV2Quoter.Quote memory quote = ITraderJoeV2Quoter(quoter).findBestPathFromAmountIn(
tokenPath,
uint128(amount)
);
binStep = ITraderJoeV2Pool(pool).feeParameters().binStep;
return (quote.amounts[1], quote.binSteps[0], uint256(quote.versions[0]));
}
function deployFQTAndGetDeploymentNonce(

View File

@@ -29,6 +29,7 @@ import "src/features/TransformERC20Feature.sol";
import "src/features/OtcOrdersFeature.sol";
import "src/features/MetaTransactionsFeature.sol";
import "src/features/MetaTransactionsFeatureV2.sol";
import "src/features/DCAFeature.sol";
import "src/features/nft_orders/ERC1155OrdersFeature.sol";
import "src/features/nft_orders/ERC721OrdersFeature.sol";
import "src/features/UniswapFeature.sol";
@@ -70,6 +71,7 @@ contract DeployZeroEx is Test {
TransformERC20Feature transformERC20Feature;
MetaTransactionsFeature metaTransactionsFeature;
MetaTransactionsFeatureV2 metaTransactionsFeatureV2;
DCAFeature dcaFeature;
ERC1155OrdersFeature erc1155OrdersFeature;
ERC721OrdersFeature erc721OrdersFeature;
MultiplexFeature multiplexFeature;
@@ -139,6 +141,7 @@ contract DeployZeroEx is Test {
"MetaTransactionsFeatureV2",
address(ZERO_EX_DEPLOYED.features.metaTransactionsFeatureV2)
);
emit log_named_address("DCAFeature", address(ZERO_EX_DEPLOYED.features.dcaFeature));
emit log_named_address("ERC1155OrdersFeature", address(ZERO_EX_DEPLOYED.features.erc1155OrdersFeature));
emit log_named_address("ERC721OrdersFeature", address(ZERO_EX_DEPLOYED.features.erc721OrdersFeature));
emit log_named_address("TransformERC20Feature", address(ZERO_EX_DEPLOYED.features.transformERC20Feature));
@@ -229,6 +232,8 @@ contract DeployZeroEx is Test {
ZERO_EX_DEPLOY_CONFIG.sushiswapPairInitCodeHash
);
ZERO_EX_DEPLOYED.features.dcaFeature = new DCAFeature(address(ZERO_EX));
initialMigration.initializeZeroEx(
payable(address(this)),
ZERO_EX,
@@ -285,6 +290,11 @@ contract DeployZeroEx is Test {
abi.encodeWithSelector(MetaTransactionsFeatureV2.migrate.selector),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.dcaFeature),
abi.encodeWithSelector(DCAFeature.migrate.selector),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.erc1155OrdersFeature),
abi.encodeWithSelector(ERC1155OrdersFeature.migrate.selector),

View File

@@ -93,7 +93,7 @@ struct LiquiditySources {
address KyberElasticPool;
address KyberElasticQuoter;
address KyberElasticRouter;
address TraderJoeV2Pool;
address TraderJoeV2Quoter;
address TraderJoeV2Router;
address UniswapV2Router;
address UniswapV3Router;
@@ -103,35 +103,27 @@ interface IFQT {
function bridgeAdapter() external returns (address);
}
interface ITraderJoeV2Pool {
struct FeeParameters {
// 144 lowest bits in slot
uint16 binStep;
uint16 baseFactor;
uint16 filterPeriod;
uint16 decayPeriod;
uint16 reductionFactor;
uint24 variableFeeControl;
uint16 protocolShare;
uint24 maxVolatilityAccumulated;
// 112 highest bits in slot
uint24 volatilityAccumulated;
uint24 volatilityReference;
uint24 indexRef;
uint40 time;
interface ITraderJoeV2Quoter {
enum Version {
V1,
V2,
V2_1
}
function feeParameters() external view returns (FeeParameters memory);
struct Quote {
address[] route;
address[] pairs;
uint256[] binSteps;
Version[] versions;
uint128[] amounts;
uint128[] virtualAmountsWithoutSlippage;
uint128[] fees;
}
function tokenY() external view returns (address);
}
interface ITraderJoeV2Router {
function getSwapOut(
address pool,
uint256 amountIn,
bool swapForY
) external view returns (uint256 amountOut, uint256 feesIn);
function findBestPathFromAmountIn(
address[] calldata route,
uint128 amountIn
) external view returns (Quote memory quote);
}
interface IKyberElasticQuoter {

View File

@@ -19,14 +19,14 @@ The following contracts are in scope of the bug bounty. Please note that any bug
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| **Release** | **Contracts** | **Commit Hash** |
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| Exchange V4 | * Documentation at `https://protocol.0x.org/en/latest/ <https://protocol.0x.org/en/latest/>`__ | `c1177416f5 <https://github.com/0xProject/protocol/tree/c1177416f50c2465ee030dacc14ff996eebd4e74/contracts>`__ |
| | * `ZeroEx.sol <https://github.com/0xProject/protocol/tree/c1177416f50c2465ee030dacc14ff996eebd4e74/contracts/zero-ex/contracts/src/ZeroEx.sol>`__ | |
| | * `ZeroExOptimized.sol <https://github.com/0xProject/protocol/tree/c1177416f50c2465ee030dacc14ff996eebd4e74/contracts/zero-ex/contracts/src/ZeroExOptimized.sol>`__ | |
| | * `external/*.sol <https://github.com/0xProject/protocol/tree/c1177416f50c2465ee030dacc14ff996eebd4e74/contracts/zero-ex/contracts/src/external>`__ | |
| | * `features/**.sol <https://github.com/0xProject/protocol/tree/c1177416f50c2465ee030dacc14ff996eebd4e74/contracts/zero-ex/contracts/src/features>`__ | |
| | * `fixins/*.sol <https://github.com/0xProject/protocol/tree/c1177416f50c2465ee030dacc14ff996eebd4e74/contracts/zero-ex/contracts/src/fixins>`__ | |
| | * `migrations/*.sol <https://github.com/0xProject/protocol/tree/c1177416f50c2465ee030dacc14ff996eebd4e74/contracts/zero-ex/contracts/src/migrations>`__ | |
| | * `storage/*.sol <https://github.com/0xProject/protocol/tree/c1177416f50c2465ee030dacc14ff996eebd4e74/contracts/zero-ex/contracts/src/storage>`__ | |
| Exchange V4 | * Documentation at `https://docs.0xProtocol.org/en/latest/ <https://docs.0xProtocol.org/en/latest/>`__ | |
| | * `ZeroEx.sol <https://github.com/0xProject/protocol/tree/development/contracts/zero-ex/contracts/src/ZeroEx.sol>`__ | |
| | * `ZeroExOptimized.sol <https://github.com/0xProject/protocol/tree/development/contracts/zero-ex/contracts/src/ZeroExOptimized.sol>`__ | |
| | * `external/*.sol <https://github.com/0xProject/protocol/tree/development/contracts/zero-ex/contracts/src/external>`__ | |
| | * `features/*.sol <https://github.com/0xProject/protocol/tree/development/contracts/zero-ex/contracts/src/features>`__ | |
| | * `fixins/*.sol <https://github.com/0xProject/protocol/tree/development/contracts/zero-ex/contracts/src/fixins>`__ | |
| | * `migrations/*.sol <https://github.com/0xProject/protocol/tree/development/contracts/zero-ex/contracts/src/migrations>`__ | |
| | * `storage/*.sol <https://github.com/0xProject/protocol/tree/development/contracts/zero-ex/contracts/src/storage>`__ | |
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| Exchange V3 | * `ERC20BridgeProxy.sol <https://github.com/0xProject/0x-monorepo/blob/fb8360edfd4f42f2d2b127b95c156eb1b0daa02b/contracts/asset-proxy/contracts/src/ERC20BridgeProxy.sol>`_ (`spec <https://github.com/0xProject/0x-protocol-specification/blob/master/asset-proxy/erc20-bridge-proxy.md>`__) | `fb8360edfd <https://github.com/0xProject/0x-monorepo/tree/fb8360edfd4f42f2d2b127b95c156eb1b0daa02b/contracts>`__ |
| | * `Exchange.sol <https://github.com/0xProject/0x-monorepo/blob/fb8360edfd4f42f2d2b127b95c156eb1b0daa02b/contracts/exchange/contracts/src/Exchange.sol>`__ (`spec <https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md>`__) | |
@@ -46,8 +46,6 @@ The following contracts are in scope of the bug bounty. Please note that any bug
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| ERC20BridgeProxy | * `ERC20BridgeProxy.sol <https://github.com/0xProject/0x-monorepo/blob/281658ba349a2c5088b40b503998bea5020284a6/contracts/asset-proxy/contracts/src/ERC20BridgeProxy.sol>`__ | `281658ba34 <https://github.com/0xProject/0x-monorepo/tree/281658ba349a2c5088b40b503998bea5020284a6/contracts>`_ |
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| ExchangeProxy | * `contracts/src <https://github.com/0xProject/protocol/tree/c1177416f50c2465ee030dacc14ff996eebd4e74/contracts/zero-ex/contracts/src>`__ | `c1177416f5 <https://github.com/0xProject/protocol/tree/c1177416f50c2465ee030dacc14ff996eebd4e74/contracts/zero-ex/contracts/src>`_ |
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
Bounties
--------
@@ -67,19 +65,10 @@ The final reward amount is at the sole discretion of 0x Labs and will be paid in
| Low (CVSS 0.0 - 3.9) | up to $5,000 |
+----------------------------+---------------------+
Recent Inclusions
-----------------
+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| **Change** | **** |
+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| NFT feature | * Trade ERC721 and ERC1155 assets. See `ZEIP-93 <https://github.com/0xProject/ZEIPs/issues/93>`__ for more details |
+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
Disclosures
-----------
Please e-mail all submissions to security@0x.org with the subject "BUG BOUNTY". Your submission
should include any steps required to reproduce or exploit the vulnerability. Please allow time for
the vulnerability to be fixed before discussing any findings publicly. After receiving a submission,
we will contact you with expected timelines for a fix to be implemented.
we will contact you with expected timelines for a fix to be implemented.

View File

@@ -295,7 +295,7 @@ In both cases, the ``@0x/protocol-utils`` package simplifies generating these si
The Orderbook
=======================
Orders can be hosted by any server and are usually represented as a JSON object off-chain. For example, one off-chain way to post and discover orders is through `0x API <https://0x.org/api>`_.
Orders can be hosted by any server and are usually represented as a JSON object off-chain. For example, one off-chain way to post and discover orders is through `0x Orderbook API <https://0x.org/docs/category/orderbook-api>`_.
Below is a table represention and example of how orders should be formatted off-chain.

View File

@@ -1,4 +1,22 @@
[
{
"version": "8.7.0",
"changes": [
{
"note": "Add Trader Joe V2 MixIn to Arbitrum"
}
],
"timestamp": 1683749017
},
{
"version": "8.6.0",
"changes": [
{
"note": "Add Trader Joe V2.1 Router Support for MixIn"
}
],
"timestamp": 1682976338
},
{
"version": "8.5.0",
"changes": [

View File

@@ -6,6 +6,12 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v8.7.0 - _May 10, 2023_
* Add Trader Joe V2 MixIn to Arbitrum
## v8.6.0 - _May 1, 2023_
* Add Trader Joe V2.1 Router Support for MixIn
## v8.5.0 - _April 20, 2023_
* Add Trader Joe V2 support on Avalanche

View File

@@ -156,7 +156,7 @@
"wethTransformer": "0x9b8b52391071d71cd4ad1e61d7f273268fa34c6c",
"payTakerTransformer": "0xb9a4c32547bc3cdc2ee2fb13cc1a0717dac9888f",
"affiliateFeeTransformer": "0x105679f99d668001370b4621ad8648ac570c860f",
"fillQuoteTransformer": "0x540079df6023d39b2686fd9f6c06f1f8f66aca4a",
"fillQuoteTransformer": "0x886e4f97d7e06ab66dba574a7a861046dcf7ae4f",
"positiveSlippageFeeTransformer": "0xadbfdc58a24b6dbc16f21541800f43dd6e282250"
}
},
@@ -248,7 +248,7 @@
"wethTransformer": "0x10e968968f49dd66a5efeebbb2edcb9c49c4fc49",
"payTakerTransformer": "0xd81e65fc9bb7323bdbef8b2cdddd3b83fe41d630",
"affiliateFeeTransformer": "0x970e318b8f074c20bf0cee06970f01dc7a761e50",
"fillQuoteTransformer": "0x5d3a221bad31c3f3c07bea2f1de9b3ec17664b69",
"fillQuoteTransformer": "0x4a8815c2fc605e3b01aee52aade4d096c4e862c6",
"positiveSlippageFeeTransformer": "0x20f935b037e8490d8027f2751f9452725eee01ad"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contract-addresses",
"version": "8.5.0",
"version": "8.7.0",
"engines": {
"node": ">=6.12"
},

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1683749017,
"version": "13.23.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1682976338,
"version": "13.23.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "13.23.0",
"changes": [

View File

@@ -6,6 +6,12 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v13.23.2 - _May 10, 2023_
* Dependencies updated
## v13.23.1 - _May 1, 2023_
* Dependencies updated
## v13.23.0 - _April 24, 2023_
* Regenerate IZeroEx wrapper

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contract-wrappers",
"version": "13.23.0",
"version": "13.23.2",
"engines": {
"node": ">=6.12"
},
@@ -59,7 +59,7 @@
"dependencies": {
"@0x/assert": "^3.0.36",
"@0x/base-contract": "^7.0.0",
"@0x/contract-addresses": "^8.5.0",
"@0x/contract-addresses": "^8.7.0",
"@0x/json-schemas": "^6.4.4",
"@0x/types": "^3.3.7",
"@0x/utils": "^7.0.0",

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1683749017,
"version": "11.22.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1682976338,
"version": "11.22.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "11.22.0",
"changes": [

View File

@@ -6,6 +6,12 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v11.22.2 - _May 10, 2023_
* Dependencies updated
## v11.22.1 - _May 1, 2023_
* Dependencies updated
## v11.22.0 - _April 24, 2023_
* Add MetaTransactionV2 utilities

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/protocol-utils",
"version": "11.22.0",
"version": "11.22.2",
"engines": {
"node": ">=6.12"
},
@@ -62,8 +62,8 @@
},
"dependencies": {
"@0x/assert": "^3.0.36",
"@0x/contract-addresses": "^8.5.0",
"@0x/contract-wrappers": "^13.23.0",
"@0x/contract-addresses": "^8.7.0",
"@0x/contract-wrappers": "^13.23.2",
"@0x/json-schemas": "^6.4.4",
"@0x/subproviders": "^8.0.1",
"@0x/utils": "^7.0.0",