Compare commits

..

17 Commits

Author SHA1 Message Date
Github Actions
bb4a9c656c Publish
- @0x/contracts-erc20@3.3.23
 - @0x/contracts-test-utils@5.4.14
 - @0x/contracts-treasury@1.4.6
 - @0x/contracts-utils@4.8.4
 - @0x/contracts-zero-ex@0.29.5
 - @0x/asset-swapper@16.34.0
 - @0x/contract-addresses@6.9.0
 - @0x/contract-wrappers@13.18.3
 - @0x/migrations@8.1.12
 - @0x/protocol-utils@1.9.5
2021-11-16 22:49:46 +00:00
Github Actions
6ab07b6304 Updated CHANGELOGS & MD docs 2021-11-16 22:49:43 +00:00
Noah Khamliche
8903f1ab01 Update packages/contract-addresses/CHANGELOG.json
Co-authored-by: Lawrence Forman <lawrence@0xproject.com>
2021-11-16 16:55:57 -05:00
Noah Khamliche
415535612a removed duplicate celo code 2021-11-16 16:55:57 -05:00
Noah Khamliche
5248a135c3 upped versions in changelog 2021-11-16 16:55:57 -05:00
Lawrence Forman
602290925c fix celo rebase 2021-11-16 16:55:57 -05:00
Github Actions
01813746e8 Publish
- @0x/contracts-zero-ex@0.29.4
 - @0x/asset-swapper@16.33.0
 - @0x/migrations@8.1.11
2021-11-16 12:27:06 +00:00
Github Actions
7d668d8801 Updated CHANGELOGS & MD docs 2021-11-16 12:27:02 +00:00
Jacob Evans
797a00a33a feat: Uniswap V3 1bps pools [TKR-263] (#366)
* feat: Uniswap V3 1bps pools

* Update CHANGELOG
2021-11-16 08:15:24 +10:00
Lawrence Forman
4b3d98f43c @0x/contracts-zero-ex: Prevent EP ETH balance from reducing when executin mtxs (#365)
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2021-11-09 22:11:36 -05:00
Github Actions
9ff77c1cd5 Publish
- @0x/asset-swapper@16.32.0
2021-11-09 19:36:14 +00:00
Github Actions
18a8351671 Updated CHANGELOGS & MD docs 2021-11-09 19:36:10 +00:00
Jorge Pérez
9a994dfcd3 fix: Extended Quote Report Changelog typo 2021-11-09 13:17:14 -06:00
Jorge Pérez
b7adc5a889 feat: Extended Quote Report
* Extended Quote report for indicative quote

* feat: Only save 'full' quotes on quote report

* Unify extended quote report
2021-11-09 13:05:01 -06:00
Github Actions
10b0d7f363 Publish
- @0x/asset-swapper@16.31.0
2021-11-04 06:52:28 +00:00
Github Actions
e2c905a15f Updated CHANGELOGS & MD docs 2021-11-04 06:52:25 +00:00
Jacob Evans
8589ba728c feat: [Avalanche] Add Curve, CurveV2 and KyberDMM (#363)
* feat: [Avalanche] Add Curve, CurveV2 and KyberDMM

* CHANGELOG

* fix missing file

* lint
2021-11-04 16:34:48 +10:00
53 changed files with 813 additions and 152 deletions

View File

@@ -1,4 +1,13 @@
[ [
{
"timestamp": 1637102971,
"version": "3.3.23",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1635903615, "timestamp": 1635903615,
"version": "3.3.22", "version": "3.3.22",

View File

@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v3.3.23 - _November 16, 2021_
* Dependencies updated
## v3.3.22 - _November 3, 2021_ ## v3.3.22 - _November 3, 2021_
* Dependencies updated * Dependencies updated

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contracts-erc20", "name": "@0x/contracts-erc20",
"version": "3.3.22", "version": "3.3.23",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -53,8 +53,8 @@
"devDependencies": { "devDependencies": {
"@0x/abi-gen": "^5.6.2", "@0x/abi-gen": "^5.6.2",
"@0x/contracts-gen": "^2.0.40", "@0x/contracts-gen": "^2.0.40",
"@0x/contracts-test-utils": "^5.4.13", "@0x/contracts-test-utils": "^5.4.14",
"@0x/contracts-utils": "^4.8.3", "@0x/contracts-utils": "^4.8.4",
"@0x/dev-utils": "^4.2.9", "@0x/dev-utils": "^4.2.9",
"@0x/sol-compiler": "^4.7.5", "@0x/sol-compiler": "^4.7.5",
"@0x/ts-doc-gen": "^0.0.28", "@0x/ts-doc-gen": "^0.0.28",

View File

@@ -1,4 +1,13 @@
[ [
{
"timestamp": 1637102971,
"version": "5.4.14",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1635903615, "timestamp": 1635903615,
"version": "5.4.13", "version": "5.4.13",

View File

@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v5.4.14 - _November 16, 2021_
* Dependencies updated
## v5.4.13 - _November 3, 2021_ ## v5.4.13 - _November 3, 2021_
* Dependencies updated * Dependencies updated

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contracts-test-utils", "name": "@0x/contracts-test-utils",
"version": "5.4.13", "version": "5.4.14",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -44,7 +44,7 @@
"dependencies": { "dependencies": {
"@0x/assert": "^3.0.29", "@0x/assert": "^3.0.29",
"@0x/base-contract": "^6.4.2", "@0x/base-contract": "^6.4.2",
"@0x/contract-addresses": "^6.8.1", "@0x/contract-addresses": "^6.9.0",
"@0x/dev-utils": "^4.2.9", "@0x/dev-utils": "^4.2.9",
"@0x/json-schemas": "^6.3.0", "@0x/json-schemas": "^6.3.0",
"@0x/order-utils": "^10.4.28", "@0x/order-utils": "^10.4.28",

View File

@@ -1,4 +1,13 @@
[ [
{
"timestamp": 1637102971,
"version": "1.4.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1635903615, "timestamp": 1635903615,
"version": "1.4.5", "version": "1.4.5",

View File

@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.4.6 - _November 16, 2021_
* Dependencies updated
## v1.4.5 - _November 3, 2021_ ## v1.4.5 - _November 3, 2021_
* Dependencies updated * Dependencies updated

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contracts-treasury", "name": "@0x/contracts-treasury",
"version": "1.4.5", "version": "1.4.6",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -47,12 +47,12 @@
"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.6.2", "@0x/abi-gen": "^5.6.2",
"@0x/contract-addresses": "^6.8.1", "@0x/contract-addresses": "^6.9.0",
"@0x/contracts-asset-proxy": "^3.7.19", "@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-erc20": "^3.3.22", "@0x/contracts-erc20": "^3.3.23",
"@0x/contracts-gen": "^2.0.40", "@0x/contracts-gen": "^2.0.40",
"@0x/contracts-staking": "^2.0.45", "@0x/contracts-staking": "^2.0.45",
"@0x/contracts-test-utils": "^5.4.13", "@0x/contracts-test-utils": "^5.4.14",
"@0x/sol-compiler": "^4.7.5", "@0x/sol-compiler": "^4.7.5",
"@0x/ts-doc-gen": "^0.0.28", "@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4", "@0x/tslint-config": "^4.1.4",
@@ -73,7 +73,7 @@
}, },
"dependencies": { "dependencies": {
"@0x/base-contract": "^6.4.2", "@0x/base-contract": "^6.4.2",
"@0x/protocol-utils": "^1.9.4", "@0x/protocol-utils": "^1.9.5",
"@0x/subproviders": "^6.6.0", "@0x/subproviders": "^6.6.0",
"@0x/types": "^3.3.4", "@0x/types": "^3.3.4",
"@0x/typescript-typings": "^5.2.1", "@0x/typescript-typings": "^5.2.1",

View File

@@ -1,4 +1,13 @@
[ [
{
"timestamp": 1637102971,
"version": "4.8.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1635903615, "timestamp": 1635903615,
"version": "4.8.3", "version": "4.8.3",

View File

@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v4.8.4 - _November 16, 2021_
* Dependencies updated
## v4.8.3 - _November 3, 2021_ ## v4.8.3 - _November 3, 2021_
* Dependencies updated * Dependencies updated

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contracts-utils", "name": "@0x/contracts-utils",
"version": "4.8.3", "version": "4.8.4",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -52,7 +52,7 @@
"devDependencies": { "devDependencies": {
"@0x/abi-gen": "^5.6.2", "@0x/abi-gen": "^5.6.2",
"@0x/contracts-gen": "^2.0.40", "@0x/contracts-gen": "^2.0.40",
"@0x/contracts-test-utils": "^5.4.13", "@0x/contracts-test-utils": "^5.4.14",
"@0x/dev-utils": "^4.2.9", "@0x/dev-utils": "^4.2.9",
"@0x/order-utils": "^10.4.28", "@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.7.5", "@0x/sol-compiler": "^4.7.5",

View File

@@ -1,4 +1,23 @@
[ [
{
"timestamp": 1637102971,
"version": "0.29.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.29.4",
"changes": [
{
"note": "Prevent EP ETH balance from reducing when executin mtxs",
"pr": 365
}
],
"timestamp": 1637065617
},
{ {
"version": "0.29.3", "version": "0.29.3",
"changes": [ "changes": [

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v0.29.5 - _November 16, 2021_
* Dependencies updated
## v0.29.4 - _November 16, 2021_
* Prevent EP ETH balance from reducing when executin mtxs (#365)
## v0.29.3 - _November 3, 2021_ ## v0.29.3 - _November 3, 2021_
* Register transformERC20() and remove transformERC20Staging() (#355) * Register transformERC20() and remove transformERC20Staging() (#355)

View File

@@ -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, 2, 0); uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 2, 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,6 +105,17 @@ contract MetaTransactionsFeature is
} }
} }
/// @dev Ensures that the ETH balance of `this` does not go below the
/// initial ETH balance before the call (excluding ETH attached to the call).
modifier doesNotReduceEthBalance() {
uint256 initialBalance = address(this).balance - msg.value;
_;
require(
initialBalance <= address(this).balance,
"MetaTransactionsFeature/ETH_LEAK"
);
}
constructor(address zeroExAddress) constructor(address zeroExAddress)
public public
FixinCommon() FixinCommon()
@@ -140,6 +151,7 @@ contract MetaTransactionsFeature is
payable payable
override override
nonReentrant(REENTRANCY_MTX) nonReentrant(REENTRANCY_MTX)
doesNotReduceEthBalance
refundsAttachedEth refundsAttachedEth
returns (bytes memory returnResult) returns (bytes memory returnResult)
{ {
@@ -164,6 +176,7 @@ contract MetaTransactionsFeature is
payable payable
override override
nonReentrant(REENTRANCY_MTX) nonReentrant(REENTRANCY_MTX)
doesNotReduceEthBalance
refundsAttachedEth refundsAttachedEth
returns (bytes[] memory returnResults) returns (bytes[] memory returnResults)
{ {

View File

@@ -46,6 +46,10 @@ contract TestMetaTransactionsTransformERC20Feature is
payable payable
returns (uint256 outputTokenAmount) returns (uint256 outputTokenAmount)
{ {
if (msg.value == 555) {
tx.origin.transfer(1);
}
if (msg.value == 666) { if (msg.value == 666) {
revert('FAIL'); revert('FAIL');
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contracts-zero-ex", "name": "@0x/contracts-zero-ex",
"version": "0.29.3", "version": "0.29.5",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -56,10 +56,10 @@
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex", "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex",
"devDependencies": { "devDependencies": {
"@0x/abi-gen": "^5.6.2", "@0x/abi-gen": "^5.6.2",
"@0x/contract-addresses": "^6.8.1", "@0x/contract-addresses": "^6.9.0",
"@0x/contracts-erc20": "^3.3.22", "@0x/contracts-erc20": "^3.3.23",
"@0x/contracts-gen": "^2.0.40", "@0x/contracts-gen": "^2.0.40",
"@0x/contracts-test-utils": "^5.4.13", "@0x/contracts-test-utils": "^5.4.14",
"@0x/dev-utils": "^4.2.9", "@0x/dev-utils": "^4.2.9",
"@0x/order-utils": "^10.4.28", "@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.7.5", "@0x/sol-compiler": "^4.7.5",
@@ -83,7 +83,7 @@
}, },
"dependencies": { "dependencies": {
"@0x/base-contract": "^6.4.2", "@0x/base-contract": "^6.4.2",
"@0x/protocol-utils": "^1.9.4", "@0x/protocol-utils": "^1.9.5",
"@0x/subproviders": "^6.6.0", "@0x/subproviders": "^6.6.0",
"@0x/types": "^3.3.4", "@0x/types": "^3.3.4",
"@0x/typescript-typings": "^5.2.1", "@0x/typescript-typings": "^5.2.1",

View File

@@ -38,6 +38,7 @@ blockchainTests.resets('MetaTransactions feature', env => {
let nativeOrdersFeature: TestMetaTransactionsNativeOrdersFeatureContract; let nativeOrdersFeature: TestMetaTransactionsNativeOrdersFeatureContract;
const MAX_FEE_AMOUNT = new BigNumber('1e18'); const MAX_FEE_AMOUNT = new BigNumber('1e18');
const TRANSFORM_ERC20_ONE_WEI_VALUE = new BigNumber(555);
const TRANSFORM_ERC20_FAILING_VALUE = new BigNumber(666); const TRANSFORM_ERC20_FAILING_VALUE = new BigNumber(666);
const TRANSFORM_ERC20_REENTER_VALUE = new BigNumber(777); const TRANSFORM_ERC20_REENTER_VALUE = new BigNumber(777);
const TRANSFORM_ERC20_BATCH_REENTER_VALUE = new BigNumber(888); const TRANSFORM_ERC20_BATCH_REENTER_VALUE = new BigNumber(888);
@@ -597,7 +598,7 @@ blockchainTests.resets('MetaTransactions feature', env => {
); );
}); });
it('cannot reenter `executeMetaTransaction()`', async () => { it('cannot reduce initial ETH balance', async () => {
const args = getRandomTransformERC20Args(); const args = getRandomTransformERC20Args();
const mtx = getRandomMetaTransaction({ const mtx = getRandomMetaTransaction({
callData: transformERC20Feature callData: transformERC20Feature
@@ -609,58 +610,23 @@ blockchainTests.resets('MetaTransactions feature', env => {
args.transformations, args.transformations,
) )
.getABIEncodedTransactionData(), .getABIEncodedTransactionData(),
value: TRANSFORM_ERC20_REENTER_VALUE, value: TRANSFORM_ERC20_ONE_WEI_VALUE,
}); });
const mtxHash = mtx.getHash();
const signature = await mtx.getSignatureWithProviderAsync(env.provider); const signature = await mtx.getSignatureWithProviderAsync(env.provider);
const callOpts = { const callOpts = {
gasPrice: mtx.maxGasPrice, gasPrice: mtx.maxGasPrice,
value: mtx.value, value: mtx.value,
}; };
const tx = feature.executeMetaTransaction(mtx, signature).awaitTransactionSuccessAsync(callOpts); // Send pre-existing ETH to the EP.
return expect(tx).to.revertWith( await env.web3Wrapper.awaitTransactionSuccessAsync(
new ZeroExRevertErrors.MetaTransactions.MetaTransactionCallFailedError( await env.web3Wrapper.sendTransactionAsync({
mtxHash, from: owner,
undefined, to: zeroEx.address,
new ZeroExRevertErrors.Common.IllegalReentrancyError( value: new BigNumber(1),
feature.getSelector('executeMetaTransaction'), }),
REENTRANCY_FLAG_MTX,
).encode(),
),
); );
});
it('cannot reenter `batchExecuteMetaTransactions()`', async () => {
const args = getRandomTransformERC20Args();
const mtx = getRandomMetaTransaction({
callData: transformERC20Feature
.transformERC20(
args.inputToken,
args.outputToken,
args.inputTokenAmount,
args.minOutputTokenAmount,
args.transformations,
)
.getABIEncodedTransactionData(),
value: TRANSFORM_ERC20_BATCH_REENTER_VALUE,
});
const mtxHash = mtx.getHash();
const signature = await mtx.getSignatureWithProviderAsync(env.provider);
const callOpts = {
gasPrice: mtx.maxGasPrice,
value: mtx.value,
};
const tx = feature.executeMetaTransaction(mtx, signature).awaitTransactionSuccessAsync(callOpts); const tx = feature.executeMetaTransaction(mtx, signature).awaitTransactionSuccessAsync(callOpts);
return expect(tx).to.revertWith( return expect(tx).to.revertWith('MetaTransactionsFeature/ETH_LEAK');
new ZeroExRevertErrors.MetaTransactions.MetaTransactionCallFailedError(
mtxHash,
undefined,
new ZeroExRevertErrors.Common.IllegalReentrancyError(
feature.getSelector('batchExecuteMetaTransactions'),
REENTRANCY_FLAG_MTX,
).encode(),
),
);
}); });
}); });
@@ -817,6 +783,37 @@ blockchainTests.resets('MetaTransactions feature', env => {
), ),
); );
}); });
it('cannot reduce initial ETH balance', async () => {
const args = getRandomTransformERC20Args();
const mtx = getRandomMetaTransaction({
callData: transformERC20Feature
.transformERC20(
args.inputToken,
args.outputToken,
args.inputTokenAmount,
args.minOutputTokenAmount,
args.transformations,
)
.getABIEncodedTransactionData(),
value: TRANSFORM_ERC20_ONE_WEI_VALUE,
});
const signature = await mtx.getSignatureWithProviderAsync(env.provider);
const callOpts = {
gasPrice: mtx.maxGasPrice,
value: mtx.value,
};
// Send pre-existing ETH to the EP.
await env.web3Wrapper.awaitTransactionSuccessAsync(
await env.web3Wrapper.sendTransactionAsync({
from: owner,
to: zeroEx.address,
value: new BigNumber(1),
}),
);
const tx = feature.batchExecuteMetaTransactions([mtx], [signature]).awaitTransactionSuccessAsync(callOpts);
return expect(tx).to.revertWith('MetaTransactionsFeature/ETH_LEAK');
});
}); });
describe('getMetaTransactionExecutedBlock()', () => { describe('getMetaTransactionExecutedBlock()', () => {

View File

@@ -1,4 +1,44 @@
[ [
{
"version": "16.34.0",
"changes": [
{
"note": "Add support Celo",
"pr": 367
}
],
"timestamp": 1637102971
},
{
"version": "16.33.0",
"changes": [
{
"note": "Add support for Uniswap V3 1 bps pools",
"pr": 366
}
],
"timestamp": 1637065617
},
{
"version": "16.32.0",
"changes": [
{
"note": "Extended Quote Report",
"pr": 361
}
],
"timestamp": 1636480845
},
{
"timestamp": 1635903615,
"version": "16.31.0",
"changes": [
{
"note": "Added `Curve`, `Curve_V2` and `KyberDmm` to Avalanche",
"pr": 363
}
]
},
{ {
"timestamp": 1635903615, "timestamp": 1635903615,
"version": "16.30.1", "version": "16.30.1",

View File

@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v16.34.0 - _November 16, 2021_
* Add support Celo (#367)
## v16.33.0 - _November 16, 2021_
* Add support for Uniswap V3 1 bps pools (#366)
## v16.32.0 - _November 9, 2021_
* Extended Quote Report (#361)
## v16.31.0 - _November 3, 2021_
* Added `Curve`, `Curve_V2` and `KyberDmm` to Avalanche (#363)
## v16.30.1 - _November 3, 2021_ ## v16.30.1 - _November 3, 2021_
* Dependencies updated * Dependencies updated

View File

@@ -159,8 +159,11 @@ contract KyberDmmSampler
(path[i], path[i + 1]) (path[i], path[i + 1])
returns (address[] memory allPools) returns (address[] memory allPools)
{ {
if (allPools.length == 0) {
return new address[](0);
}
uint256 maxSupply = 0; uint256 maxSupply = 0;
require(allPools.length >= 1, "KyberDMMSampler/NO_POOLS_FOUND");
for (uint256 j = 0; j < allPools.length; j++) { for (uint256 j = 0; j < allPools.length; j++) {
uint256 totalSupply = IKyberDmmPool(allPools[j]).totalSupply(); uint256 totalSupply = IKyberDmmPool(allPools[j]).totalSupply();
if (totalSupply > maxSupply) { if (totalSupply > maxSupply) {

View File

@@ -174,8 +174,9 @@ contract UniswapV3Sampler
tokenPath.length - startIndex >= 2, tokenPath.length - startIndex >= 2,
"UniswapV3Sampler/tokenPath too short" "UniswapV3Sampler/tokenPath too short"
); );
uint24[3] memory validPoolFees = [ uint24[4] memory validPoolFees = [
// The launch pool fees. Could get hairier if they add more. // The launch pool fees. Could get hairier if they add more.
uint24(0.0001e6),
uint24(0.0005e6), uint24(0.0005e6),
uint24(0.003e6), uint24(0.003e6),
uint24(0.01e6) uint24(0.01e6)

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/asset-swapper", "name": "@0x/asset-swapper",
"version": "16.30.1", "version": "16.34.0",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -60,14 +60,14 @@
"dependencies": { "dependencies": {
"@0x/assert": "^3.0.29", "@0x/assert": "^3.0.29",
"@0x/base-contract": "^6.4.2", "@0x/base-contract": "^6.4.2",
"@0x/contract-addresses": "^6.8.1", "@0x/contract-addresses": "^6.9.0",
"@0x/contract-wrappers": "^13.18.2", "@0x/contract-wrappers": "^13.18.3",
"@0x/contracts-erc20": "^3.3.22", "@0x/contracts-erc20": "^3.3.23",
"@0x/contracts-zero-ex": "^0.29.3", "@0x/contracts-zero-ex": "^0.29.5",
"@0x/dev-utils": "^4.2.9", "@0x/dev-utils": "^4.2.9",
"@0x/json-schemas": "^6.3.0", "@0x/json-schemas": "^6.3.0",
"@0x/neon-router": "^0.2.1", "@0x/neon-router": "^0.2.1",
"@0x/protocol-utils": "^1.9.4", "@0x/protocol-utils": "^1.9.5",
"@0x/quote-server": "^6.0.6", "@0x/quote-server": "^6.0.6",
"@0x/types": "^3.3.4", "@0x/types": "^3.3.4",
"@0x/typescript-typings": "^5.2.1", "@0x/typescript-typings": "^5.2.1",
@@ -98,10 +98,10 @@
"@0x/contracts-exchange": "^3.2.38", "@0x/contracts-exchange": "^3.2.38",
"@0x/contracts-exchange-libs": "^4.3.37", "@0x/contracts-exchange-libs": "^4.3.37",
"@0x/contracts-gen": "^2.0.40", "@0x/contracts-gen": "^2.0.40",
"@0x/contracts-test-utils": "^5.4.13", "@0x/contracts-test-utils": "^5.4.14",
"@0x/contracts-utils": "^4.8.3", "@0x/contracts-utils": "^4.8.4",
"@0x/mesh-rpc-client": "^9.4.2", "@0x/mesh-rpc-client": "^9.4.2",
"@0x/migrations": "^8.1.10", "@0x/migrations": "^8.1.12",
"@0x/sol-compiler": "^4.7.5", "@0x/sol-compiler": "^4.7.5",
"@0x/subproviders": "^6.6.0", "@0x/subproviders": "^6.6.0",
"@0x/ts-doc-gen": "^0.0.28", "@0x/ts-doc-gen": "^0.0.28",

View File

@@ -162,14 +162,20 @@ export {
export { ProtocolFeeUtils } from './utils/protocol_fee_utils'; export { ProtocolFeeUtils } from './utils/protocol_fee_utils';
export { export {
BridgeQuoteReportEntry, BridgeQuoteReportEntry,
jsonifyFillData,
MultiHopQuoteReportEntry, MultiHopQuoteReportEntry,
NativeLimitOrderQuoteReportEntry, NativeLimitOrderQuoteReportEntry,
NativeRfqOrderQuoteReportEntry, NativeRfqOrderQuoteReportEntry,
QuoteReport, QuoteReport,
QuoteReportEntry, QuoteReportEntry,
ExtendedQuoteReport,
ExtendedQuoteReportSources,
ExtendedQuoteReportEntry,
ExtendedQuoteReportIndexedEntry,
ExtendedQuoteReportIndexedEntryOutbound,
PriceComparisonsReport, PriceComparisonsReport,
} from './utils/quote_report_generator'; } from './utils/quote_report_generator';
export { QuoteRequestor } from './utils/quote_requestor'; export { QuoteRequestor, V4RFQIndicativeQuoteMM } from './utils/quote_requestor';
export { ERC20BridgeSamplerContract, BalanceCheckerContract, FakeTakerContract } from './wrappers'; export { ERC20BridgeSamplerContract, BalanceCheckerContract, FakeTakerContract } from './wrappers';
import { ERC20BridgeSource } from './utils/market_operation_utils/types'; import { ERC20BridgeSource } from './utils/market_operation_utils/types';
export type Native = ERC20BridgeSource.Native; export type Native = ERC20BridgeSource.Native;

View File

@@ -360,8 +360,9 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
// Build up the transforms. // Build up the transforms.
const transforms = []; const transforms = [];
if (isFromETH) {
// Create a WETH wrapper if coming from ETH. // Create a WETH wrapper if coming from ETH.
// Dont add the wethTransformer to CELO. There is no wrap/unwrap logic for CELO.
if (isFromETH && this.chainId !== ChainId.Celo) {
transforms.push({ transforms.push({
deploymentNonce: this.transformerNonces.wethTransformer, deploymentNonce: this.transformerNonces.wethTransformer,
data: encodeWethTransformerData({ data: encodeWethTransformerData({
@@ -413,9 +414,9 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
}), }),
}); });
} }
if (isToETH) {
// Create a WETH unwrapper if going to ETH. // Create a WETH unwrapper if going to ETH.
// Dont add the wethTransformer on CELO. There is no wrap/unwrap logic for CELO.
if (isToETH && this.chainId !== ChainId.Celo) {
transforms.push({ transforms.push({
deploymentNonce: this.transformerNonces.wethTransformer, deploymentNonce: this.transformerNonces.wethTransformer,
data: encodeWethTransformerData({ data: encodeWethTransformerData({
@@ -492,10 +493,11 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
amounts: [], amounts: [],
}), }),
}); });
const TO_ETH_ADDRESS = this.chainId === ChainId.Celo ? this.contractAddresses.etherToken : ETH_TOKEN_ADDRESS;
const calldataHexString = this._exchangeProxy const calldataHexString = this._exchangeProxy
.transformERC20( .transformERC20(
isFromETH ? ETH_TOKEN_ADDRESS : sellToken, isFromETH ? ETH_TOKEN_ADDRESS : sellToken,
isToETH ? ETH_TOKEN_ADDRESS : buyToken, isToETH ? TO_ETH_ADDRESS : buyToken,
shouldSellEntireBalance ? MAX_UINT256 : sellAmount, shouldSellEntireBalance ? MAX_UINT256 : sellAmount,
minBuyAmount, minBuyAmount,
transforms, transforms,

View File

@@ -505,6 +505,7 @@ function createSwapQuote(
const { const {
optimizedOrders, optimizedOrders,
quoteReport, quoteReport,
extendedQuoteReportSources,
sourceFlags, sourceFlags,
takerAmountPerEth, takerAmountPerEth,
makerAmountPerEth, makerAmountPerEth,
@@ -532,6 +533,7 @@ function createSwapQuote(
takerAmountPerEth, takerAmountPerEth,
makerAmountPerEth, makerAmountPerEth,
quoteReport, quoteReport,
extendedQuoteReportSources,
isTwoHop, isTwoHop,
priceComparisonsReport, priceComparisonsReport,
}; };

View File

@@ -19,7 +19,7 @@ import {
OptimizedMarketOrder, OptimizedMarketOrder,
TokenAdjacencyGraph, TokenAdjacencyGraph,
} from './utils/market_operation_utils/types'; } from './utils/market_operation_utils/types';
import { PriceComparisonsReport, QuoteReport } from './utils/quote_report_generator'; import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from './utils/quote_report_generator';
import { MetricsProxy } from './utils/quote_requestor'; import { MetricsProxy } from './utils/quote_requestor';
/** /**
@@ -171,6 +171,7 @@ export interface SwapQuoteBase {
worstCaseQuoteInfo: SwapQuoteInfo; worstCaseQuoteInfo: SwapQuoteInfo;
sourceBreakdown: SwapQuoteOrdersBreakdown; sourceBreakdown: SwapQuoteOrdersBreakdown;
quoteReport?: QuoteReport; quoteReport?: QuoteReport;
extendedQuoteReportSources?: ExtendedQuoteReportSources;
priceComparisonsReport?: PriceComparisonsReport; priceComparisonsReport?: PriceComparisonsReport;
isTwoHop: boolean; isTwoHop: boolean;
makerTokenDecimals: number; makerTokenDecimals: number;

View File

@@ -11,9 +11,11 @@ import {
COMETHSWAP_ROUTER_BY_CHAIN_ID, COMETHSWAP_ROUTER_BY_CHAIN_ID,
COMPONENT_POOLS_BY_CHAIN_ID, COMPONENT_POOLS_BY_CHAIN_ID,
CRYPTO_COM_ROUTER_BY_CHAIN_ID, CRYPTO_COM_ROUTER_BY_CHAIN_ID,
CURVE_AVALANCHE_INFOS,
CURVE_FANTOM_INFOS, CURVE_FANTOM_INFOS,
CURVE_MAINNET_INFOS, CURVE_MAINNET_INFOS,
CURVE_POLYGON_INFOS, CURVE_POLYGON_INFOS,
CURVE_V2_AVALANCHE_INFOS,
CURVE_V2_FANTOM_INFOS, CURVE_V2_FANTOM_INFOS,
CURVE_V2_MAINNET_INFOS, CURVE_V2_MAINNET_INFOS,
CURVE_V2_POLYGON_INFOS, CURVE_V2_POLYGON_INFOS,
@@ -47,6 +49,7 @@ import {
SUSHISWAP_ROUTER_BY_CHAIN_ID, SUSHISWAP_ROUTER_BY_CHAIN_ID,
SWERVE_MAINNET_INFOS, SWERVE_MAINNET_INFOS,
TRADER_JOE_ROUTER_BY_CHAIN_ID, TRADER_JOE_ROUTER_BY_CHAIN_ID,
UBESWAP_ROUTER_BY_CHAIN_ID,
UNISWAPV2_ROUTER_BY_CHAIN_ID, UNISWAPV2_ROUTER_BY_CHAIN_ID,
WAULTSWAP_ROUTER_BY_CHAIN_ID, WAULTSWAP_ROUTER_BY_CHAIN_ID,
XSIGMA_MAINNET_INFOS, XSIGMA_MAINNET_INFOS,
@@ -146,6 +149,15 @@ export function getCurveInfosForPair(chainId: ChainId, takerToken: string, maker
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0), [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
), ),
); );
case ChainId.Avalanche:
return Object.values(CURVE_AVALANCHE_INFOS).filter(c =>
[makerToken, takerToken].every(
t =>
(c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) &&
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
),
);
default: default:
return []; return [];
} }
@@ -181,6 +193,15 @@ export function getCurveV2InfosForPair(chainId: ChainId, takerToken: string, mak
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0), [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
), ),
); );
case ChainId.Avalanche:
return Object.values(CURVE_V2_AVALANCHE_INFOS).filter(c =>
[makerToken, takerToken].every(
t =>
(c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) &&
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
),
);
default: default:
return []; return [];
} }
@@ -466,6 +487,7 @@ export function uniswapV2LikeRouterAddress(
| ERC20BridgeSource.JetSwap | ERC20BridgeSource.JetSwap
| ERC20BridgeSource.TraderJoe | ERC20BridgeSource.TraderJoe
| ERC20BridgeSource.Pangolin | ERC20BridgeSource.Pangolin
| ERC20BridgeSource.UbeSwap
| ERC20BridgeSource.SpookySwap | ERC20BridgeSource.SpookySwap
| ERC20BridgeSource.SpiritSwap, | ERC20BridgeSource.SpiritSwap,
): string { ): string {
@@ -508,6 +530,8 @@ export function uniswapV2LikeRouterAddress(
return PANGOLIN_ROUTER_BY_CHAIN_ID[chainId]; return PANGOLIN_ROUTER_BY_CHAIN_ID[chainId];
case ERC20BridgeSource.TraderJoe: case ERC20BridgeSource.TraderJoe:
return TRADER_JOE_ROUTER_BY_CHAIN_ID[chainId]; return TRADER_JOE_ROUTER_BY_CHAIN_ID[chainId];
case ERC20BridgeSource.UbeSwap:
return UBESWAP_ROUTER_BY_CHAIN_ID[chainId];
case ERC20BridgeSource.SpookySwap: case ERC20BridgeSource.SpookySwap:
return SPOOKYSWAP_ROUTER_BY_CHAIN_ID[chainId]; return SPOOKYSWAP_ROUTER_BY_CHAIN_ID[chainId];
case ERC20BridgeSource.SpiritSwap: case ERC20BridgeSource.SpiritSwap:

View File

@@ -58,6 +58,7 @@ function valueByChainId<T>(rest: Partial<{ [key in ChainId]: T }>, defaultValue:
[ChainId.PolygonMumbai]: defaultValue, [ChainId.PolygonMumbai]: defaultValue,
[ChainId.Avalanche]: defaultValue, [ChainId.Avalanche]: defaultValue,
[ChainId.Fantom]: defaultValue, [ChainId.Fantom]: defaultValue,
[ChainId.Celo]: defaultValue,
...(rest || {}), ...(rest || {}),
}; };
} }
@@ -136,6 +137,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.FirebirdOneSwap, ERC20BridgeSource.FirebirdOneSwap,
ERC20BridgeSource.JetSwap, ERC20BridgeSource.JetSwap,
ERC20BridgeSource.ACryptos, ERC20BridgeSource.ACryptos,
ERC20BridgeSource.KyberDmm,
]), ]),
[ChainId.Polygon]: new SourceFilters([ [ChainId.Polygon]: new SourceFilters([
ERC20BridgeSource.SushiSwap, ERC20BridgeSource.SushiSwap,
@@ -163,6 +165,9 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Pangolin, ERC20BridgeSource.Pangolin,
ERC20BridgeSource.TraderJoe, ERC20BridgeSource.TraderJoe,
ERC20BridgeSource.SushiSwap, ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.Curve,
ERC20BridgeSource.CurveV2,
ERC20BridgeSource.KyberDmm,
]), ]),
[ChainId.Fantom]: new SourceFilters([ [ChainId.Fantom]: new SourceFilters([
ERC20BridgeSource.MultiHop, ERC20BridgeSource.MultiHop,
@@ -172,6 +177,11 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.SpookySwap, ERC20BridgeSource.SpookySwap,
ERC20BridgeSource.SushiSwap, ERC20BridgeSource.SushiSwap,
]), ]),
[ChainId.Celo]: new SourceFilters([
ERC20BridgeSource.UbeSwap,
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.MultiHop,
]),
}, },
new SourceFilters([]), new SourceFilters([]),
); );
@@ -250,6 +260,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.FirebirdOneSwap, ERC20BridgeSource.FirebirdOneSwap,
ERC20BridgeSource.JetSwap, ERC20BridgeSource.JetSwap,
ERC20BridgeSource.ACryptos, ERC20BridgeSource.ACryptos,
ERC20BridgeSource.KyberDmm,
]), ]),
[ChainId.Polygon]: new SourceFilters([ [ChainId.Polygon]: new SourceFilters([
ERC20BridgeSource.SushiSwap, ERC20BridgeSource.SushiSwap,
@@ -277,6 +288,9 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Pangolin, ERC20BridgeSource.Pangolin,
ERC20BridgeSource.TraderJoe, ERC20BridgeSource.TraderJoe,
ERC20BridgeSource.SushiSwap, ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.Curve,
ERC20BridgeSource.CurveV2,
ERC20BridgeSource.KyberDmm,
]), ]),
[ChainId.Fantom]: new SourceFilters([ [ChainId.Fantom]: new SourceFilters([
ERC20BridgeSource.MultiHop, ERC20BridgeSource.MultiHop,
@@ -286,6 +300,11 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.SpookySwap, ERC20BridgeSource.SpookySwap,
ERC20BridgeSource.SushiSwap, ERC20BridgeSource.SushiSwap,
]), ]),
[ChainId.Celo]: new SourceFilters([
ERC20BridgeSource.UbeSwap,
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.MultiHop,
]),
}, },
new SourceFilters([]), new SourceFilters([]),
); );
@@ -306,6 +325,7 @@ export const FEE_QUOTE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>
[ChainId.Polygon]: [ERC20BridgeSource.QuickSwap, ERC20BridgeSource.SushiSwap], [ChainId.Polygon]: [ERC20BridgeSource.QuickSwap, ERC20BridgeSource.SushiSwap],
[ChainId.Avalanche]: [ERC20BridgeSource.Pangolin, ERC20BridgeSource.TraderJoe, ERC20BridgeSource.SushiSwap], [ChainId.Avalanche]: [ERC20BridgeSource.Pangolin, ERC20BridgeSource.TraderJoe, ERC20BridgeSource.SushiSwap],
[ChainId.Fantom]: [ERC20BridgeSource.SpiritSwap, ERC20BridgeSource.SpookySwap, ERC20BridgeSource.SushiSwap], [ChainId.Fantom]: [ERC20BridgeSource.SpiritSwap, ERC20BridgeSource.SpookySwap, ERC20BridgeSource.SushiSwap],
[ChainId.Celo]: [ERC20BridgeSource.UbeSwap, ERC20BridgeSource.SushiSwap],
}, },
[], [],
); );
@@ -449,8 +469,19 @@ export const POLYGON_TOKENS = {
export const AVALANCHE_TOKENS = { export const AVALANCHE_TOKENS = {
WAVAX: '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7', WAVAX: '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7',
WETH: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', WETH: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab',
USDT: '0xc7198437980c041c805a1edcba50c1ce5db95118', WBTC: '0x50b7545627a5162f82a992c33b87adc75187b218',
DAI: '0xd586e7f844cea2f87f50152665bcbc2c279d8d70', DAI: '0xd586e7f844cea2f87f50152665bcbc2c279d8d70',
USDC: '0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664',
USDT: '0xc7198437980c041c805a1edcba50c1ce5db95118',
aDAI: '0x47afa96cdc9fab46904a55a6ad4bf6660b53c38a',
aUSDC: '0x46a51127c3ce23fb7ab1de06226147f446e4a857',
aUSDT: '0x532e6537fea298397212f09a61e03311686f548e',
};
export const CELO_TOKENS = {
WETH: '0xe919f65739c26a42616b7b8eedc6b5524d1e3ac4',
CELO: '0x471ece3750da237f93b8e339c536989b8978a438',
mCUSD: '0x64defa3544c695db8c535d289d843a189aa26b98',
}; };
export const FANTOM_TOKENS = { export const FANTOM_TOKENS = {
@@ -524,6 +555,14 @@ export const CURVE_V2_POLYGON_POOLS = {
atricrypto3: '0x1d8b86e3d88cdb2d34688e87e72f388cb541b7c8', atricrypto3: '0x1d8b86e3d88cdb2d34688e87e72f388cb541b7c8',
}; };
export const CURVE_AVALANCHE_POOLS = {
aave: '0x7f90122bf0700f9e7e1f688fe926940e8839f353',
};
export const CURVE_V2_AVALANCHE_POOLS = {
atricrypto: '0x58e57ca18b7a47112b877e31929798cd3d703b0f',
};
export const CURVE_FANTOM_POOLS = { export const CURVE_FANTOM_POOLS = {
fUSDT: '0x92d5ebf3593a92888c25c0abef126583d4b5312e', fUSDT: '0x92d5ebf3593a92888c25c0abef126583d4b5312e',
twoPool: '0x27e611fd27b276acbd5ffd632e5eaebec9761e40', twoPool: '0x27e611fd27b276acbd5ffd632e5eaebec9761e40',
@@ -631,8 +670,10 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
AVALANCHE_TOKENS.WETH, AVALANCHE_TOKENS.WETH,
AVALANCHE_TOKENS.DAI, AVALANCHE_TOKENS.DAI,
AVALANCHE_TOKENS.USDT, AVALANCHE_TOKENS.USDT,
AVALANCHE_TOKENS.USDC,
], ],
[ChainId.Fantom]: [FANTOM_TOKENS.WFTM, FANTOM_TOKENS.WETH, FANTOM_TOKENS.DAI, FANTOM_TOKENS.USDC], [ChainId.Fantom]: [FANTOM_TOKENS.WFTM, FANTOM_TOKENS.WETH, FANTOM_TOKENS.DAI, FANTOM_TOKENS.USDC],
[ChainId.Celo]: [CELO_TOKENS.mCUSD, CELO_TOKENS.WETH, CELO_TOKENS.CELO],
}, },
[], [],
); );
@@ -664,6 +705,9 @@ export const DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID = valueByChainId<TokenAdj
[ChainId.Fantom]: new TokenAdjacencyGraphBuilder({ [ChainId.Fantom]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Fantom], default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Fantom],
}).build(), }).build(),
[ChainId.Celo]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Celo],
}).build(),
}, },
new TokenAdjacencyGraphBuilder({ default: [] }).build(), new TokenAdjacencyGraphBuilder({ default: [] }).build(),
); );
@@ -679,6 +723,7 @@ export const NATIVE_FEE_TOKEN_BY_CHAIN_ID = valueByChainId<string>(
[ChainId.Polygon]: getContractAddressesForChainOrThrow(ChainId.Polygon).etherToken, [ChainId.Polygon]: getContractAddressesForChainOrThrow(ChainId.Polygon).etherToken,
[ChainId.Avalanche]: getContractAddressesForChainOrThrow(ChainId.Avalanche).etherToken, [ChainId.Avalanche]: getContractAddressesForChainOrThrow(ChainId.Avalanche).etherToken,
[ChainId.Fantom]: getContractAddressesForChainOrThrow(ChainId.Fantom).etherToken, [ChainId.Fantom]: getContractAddressesForChainOrThrow(ChainId.Fantom).etherToken,
[ChainId.Celo]: getContractAddressesForChainOrThrow(ChainId.Celo).etherToken,
}, },
NULL_ADDRESS, NULL_ADDRESS,
); );
@@ -999,6 +1044,37 @@ export const CURVE_V2_POLYGON_INFOS: { [name: string]: CurveInfo } = {
}), }),
}; };
export const CURVE_AVALANCHE_INFOS: { [name: string]: CurveInfo } = {
['aave_exchangeunderlying']: createCurveExchangeUnderlyingPool({
tokens: [AVALANCHE_TOKENS.DAI, AVALANCHE_TOKENS.USDC, AVALANCHE_TOKENS.USDT],
pool: CURVE_AVALANCHE_POOLS.aave,
gasSchedule: 850e3,
}),
['aave_exchange']: createCurveExchangePool({
tokens: [AVALANCHE_TOKENS.aDAI, AVALANCHE_TOKENS.aUSDC, AVALANCHE_TOKENS.aUSDT],
pool: CURVE_AVALANCHE_POOLS.aave,
gasSchedule: 150e3,
}),
};
export const CURVE_V2_AVALANCHE_INFOS: { [name: string]: CurveInfo } = {
[CURVE_V2_AVALANCHE_POOLS.atricrypto]: {
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying_v2,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying_v2,
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
tokens: [
AVALANCHE_TOKENS.DAI,
AVALANCHE_TOKENS.USDC,
AVALANCHE_TOKENS.USDT,
AVALANCHE_TOKENS.WBTC,
AVALANCHE_TOKENS.WETH,
],
metaTokens: undefined,
poolAddress: CURVE_V2_AVALANCHE_POOLS.atricrypto,
gasSchedule: 1300e3,
},
};
// TODO: modify gasSchedule // TODO: modify gasSchedule
export const CURVE_FANTOM_INFOS: { [name: string]: CurveInfo } = { export const CURVE_FANTOM_INFOS: { [name: string]: CurveInfo } = {
[CURVE_FANTOM_POOLS.ren]: createCurveExchangePool({ [CURVE_FANTOM_POOLS.ren]: createCurveExchangePool({
@@ -1320,6 +1396,7 @@ export const SUSHISWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
[ChainId.Polygon]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506', [ChainId.Polygon]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
[ChainId.Avalanche]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506', [ChainId.Avalanche]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
[ChainId.Fantom]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506', [ChainId.Fantom]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
[ChainId.Celo]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
}, },
NULL_ADDRESS, NULL_ADDRESS,
); );
@@ -1389,6 +1466,9 @@ export const KYBER_DMM_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
{ {
[ChainId.Mainnet]: '0x1c87257f5e8609940bc751a07bb085bb7f8cdbe6', [ChainId.Mainnet]: '0x1c87257f5e8609940bc751a07bb085bb7f8cdbe6',
[ChainId.Polygon]: '0x546c79662e028b661dfb4767664d0273184e4dd1', [ChainId.Polygon]: '0x546c79662e028b661dfb4767664d0273184e4dd1',
[ChainId.BSC]: '0x78df70615ffc8066cc0887917f2cd72092c86409',
[ChainId.Avalanche]: '0x8efa5a9ad6d594cf76830267077b78ce0bc5a5f8',
[ChainId.Fantom]: '0x5d5a5a0a465129848c2549669e12cdc2f8de039a',
}, },
NULL_ADDRESS, NULL_ADDRESS,
); );
@@ -1690,6 +1770,13 @@ export const TRADER_JOE_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
NULL_ADDRESS, NULL_ADDRESS,
); );
export const UBESWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Celo]: '0x7d28570135a2b1930f331c507f65039d4937f66c',
},
NULL_ADDRESS,
);
export const SPIRITSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>( export const SPIRITSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
{ {
[ChainId.Fantom]: '0x16327e3fbdaca3bcf7e38f5af2599d2ddc33ae52', [ChainId.Fantom]: '0x16327e3fbdaca3bcf7e38f5af2599d2ddc33ae52',
@@ -1855,6 +1942,11 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
[ERC20BridgeSource.Pangolin]: uniswapV2CloneGasSchedule, [ERC20BridgeSource.Pangolin]: uniswapV2CloneGasSchedule,
[ERC20BridgeSource.TraderJoe]: uniswapV2CloneGasSchedule, [ERC20BridgeSource.TraderJoe]: uniswapV2CloneGasSchedule,
//
// Celo
//
[ERC20BridgeSource.UbeSwap]: uniswapV2CloneGasSchedule,
// //
// Fantom // Fantom
// //

View File

@@ -18,12 +18,15 @@ import {
import { import {
dexSampleToReportSource, dexSampleToReportSource,
ExtendedQuoteReportSources,
generateExtendedQuoteReportSources,
generateQuoteReport, generateQuoteReport,
multiHopSampleToReportSource, multiHopSampleToReportSource,
nativeOrderToReportEntry, nativeOrderToReportEntry,
PriceComparisonsReport, PriceComparisonsReport,
QuoteReport, QuoteReport,
} from './../quote_report_generator'; } from './../quote_report_generator';
import { getComparisonPrices } from './comparison_price'; import { getComparisonPrices } from './comparison_price';
import { import {
BUY_SOURCE_FILTER_BY_CHAIN_ID, BUY_SOURCE_FILTER_BY_CHAIN_ID,
@@ -78,6 +81,25 @@ export class MarketOperationUtils {
return generateQuoteReport(side, quotes.nativeOrders, liquidityDelivered, comparisonPrice, quoteRequestor); return generateQuoteReport(side, quotes.nativeOrders, liquidityDelivered, comparisonPrice, quoteRequestor);
} }
private static _computeExtendedQuoteReportSources(
quoteRequestor: QuoteRequestor | undefined,
marketSideLiquidity: MarketSideLiquidity,
amount: BigNumber,
optimizerResult: OptimizerResult,
comparisonPrice?: BigNumber | undefined,
): ExtendedQuoteReportSources {
const { side, quotes } = marketSideLiquidity;
const { liquidityDelivered } = optimizerResult;
return generateExtendedQuoteReportSources(
side,
quotes,
liquidityDelivered,
amount,
comparisonPrice,
quoteRequestor,
);
}
private static _computePriceComparisonsReport( private static _computePriceComparisonsReport(
quoteRequestor: QuoteRequestor | undefined, quoteRequestor: QuoteRequestor | undefined,
marketSideLiquidity: MarketSideLiquidity, marketSideLiquidity: MarketSideLiquidity,
@@ -702,6 +724,16 @@ export class MarketOperationUtils {
); );
} }
// Always compute the Extended Quote Report
let extendedQuoteReportSources: ExtendedQuoteReportSources | undefined;
extendedQuoteReportSources = MarketOperationUtils._computeExtendedQuoteReportSources(
_opts.rfqt ? _opts.rfqt.quoteRequestor : undefined,
marketSideLiquidity,
amount,
optimizerResult,
wholeOrderPrice,
);
let priceComparisonsReport: PriceComparisonsReport | undefined; let priceComparisonsReport: PriceComparisonsReport | undefined;
if (_opts.shouldIncludePriceComparisonsReport) { if (_opts.shouldIncludePriceComparisonsReport) {
priceComparisonsReport = MarketOperationUtils._computePriceComparisonsReport( priceComparisonsReport = MarketOperationUtils._computePriceComparisonsReport(
@@ -710,7 +742,7 @@ export class MarketOperationUtils {
wholeOrderPrice, wholeOrderPrice,
); );
} }
return { ...optimizerResult, quoteReport, priceComparisonsReport }; return { ...optimizerResult, quoteReport, extendedQuoteReportSources, priceComparisonsReport };
} }
private async _refreshPoolCacheIfRequiredAsync(takerToken: string, makerToken: string): Promise<void> { private async _refreshPoolCacheIfRequiredAsync(takerToken: string, makerToken: string): Promise<void> {

View File

@@ -184,6 +184,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'Pangolin'); return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'Pangolin');
case ERC20BridgeSource.TraderJoe: case ERC20BridgeSource.TraderJoe:
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'TraderJoe'); return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'TraderJoe');
case ERC20BridgeSource.UbeSwap:
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'UbeSwap');
case ERC20BridgeSource.SpiritSwap: case ERC20BridgeSource.SpiritSwap:
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'SpiritSwap'); return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'SpiritSwap');
case ERC20BridgeSource.SpookySwap: case ERC20BridgeSource.SpookySwap:
@@ -264,6 +266,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
case ERC20BridgeSource.JetSwap: case ERC20BridgeSource.JetSwap:
case ERC20BridgeSource.Pangolin: case ERC20BridgeSource.Pangolin:
case ERC20BridgeSource.TraderJoe: case ERC20BridgeSource.TraderJoe:
case ERC20BridgeSource.UbeSwap:
case ERC20BridgeSource.SpiritSwap: case ERC20BridgeSource.SpiritSwap:
case ERC20BridgeSource.SpookySwap: case ERC20BridgeSource.SpookySwap:
const uniswapV2FillData = (order as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData; const uniswapV2FillData = (order as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData;
@@ -458,6 +461,8 @@ export const BRIDGE_ENCODERS: {
[ERC20BridgeSource.TraderJoe]: routerAddressPathEncoder, [ERC20BridgeSource.TraderJoe]: routerAddressPathEncoder,
[ERC20BridgeSource.SpiritSwap]: routerAddressPathEncoder, [ERC20BridgeSource.SpiritSwap]: routerAddressPathEncoder,
[ERC20BridgeSource.SpookySwap]: routerAddressPathEncoder, [ERC20BridgeSource.SpookySwap]: routerAddressPathEncoder,
// Celo
[ERC20BridgeSource.UbeSwap]: routerAddressPathEncoder,
// BSC // BSC
[ERC20BridgeSource.PancakeSwap]: routerAddressPathEncoder, [ERC20BridgeSource.PancakeSwap]: routerAddressPathEncoder,
[ERC20BridgeSource.PancakeSwapV2]: routerAddressPathEncoder, [ERC20BridgeSource.PancakeSwapV2]: routerAddressPathEncoder,

View File

@@ -1197,6 +1197,7 @@ export class SamplerOperations {
case ERC20BridgeSource.JetSwap: case ERC20BridgeSource.JetSwap:
case ERC20BridgeSource.Pangolin: case ERC20BridgeSource.Pangolin:
case ERC20BridgeSource.TraderJoe: case ERC20BridgeSource.TraderJoe:
case ERC20BridgeSource.UbeSwap:
case ERC20BridgeSource.SpiritSwap: case ERC20BridgeSource.SpiritSwap:
case ERC20BridgeSource.SpookySwap: case ERC20BridgeSource.SpookySwap:
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source); const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
@@ -1468,6 +1469,7 @@ export class SamplerOperations {
case ERC20BridgeSource.JetSwap: case ERC20BridgeSource.JetSwap:
case ERC20BridgeSource.Pangolin: case ERC20BridgeSource.Pangolin:
case ERC20BridgeSource.TraderJoe: case ERC20BridgeSource.TraderJoe:
case ERC20BridgeSource.UbeSwap:
case ERC20BridgeSource.SpiritSwap: case ERC20BridgeSource.SpiritSwap:
case ERC20BridgeSource.SpookySwap: case ERC20BridgeSource.SpookySwap:
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source); const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);

View File

@@ -3,13 +3,12 @@ import {
FillQuoteTransformerOrderType, FillQuoteTransformerOrderType,
FillQuoteTransformerRfqOrderInfo, FillQuoteTransformerRfqOrderInfo,
} from '@0x/protocol-utils'; } from '@0x/protocol-utils';
import { V4RFQIndicativeQuote } from '@0x/quote-server';
import { MarketOperation } from '@0x/types'; import { MarketOperation } from '@0x/types';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { NativeOrderWithFillableAmounts, RfqFirmQuoteValidator, RfqRequestOpts } from '../../types'; import { NativeOrderWithFillableAmounts, RfqFirmQuoteValidator, RfqRequestOpts } from '../../types';
import { QuoteRequestor } from '../../utils/quote_requestor'; import { QuoteRequestor, V4RFQIndicativeQuoteMM } from '../../utils/quote_requestor';
import { PriceComparisonsReport, QuoteReport } from '../quote_report_generator'; import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from '../quote_report_generator';
import { CollapsedPath } from './path'; import { CollapsedPath } from './path';
import { SourceFilters } from './source_filters'; import { SourceFilters } from './source_filters';
@@ -93,6 +92,8 @@ export enum ERC20BridgeSource {
// Avalanche // Avalanche
Pangolin = 'Pangolin', Pangolin = 'Pangolin',
TraderJoe = 'TraderJoe', TraderJoe = 'TraderJoe',
// Celo only
UbeSwap = 'UbeSwap',
// Fantom // Fantom
SpiritSwap = 'SpiritSwap', SpiritSwap = 'SpiritSwap',
SpookySwap = 'SpookySwap', SpookySwap = 'SpookySwap',
@@ -491,6 +492,7 @@ export interface OptimizerResult {
export interface OptimizerResultWithReport extends OptimizerResult { export interface OptimizerResultWithReport extends OptimizerResult {
quoteReport?: QuoteReport; quoteReport?: QuoteReport;
extendedQuoteReportSources?: ExtendedQuoteReportSources;
priceComparisonsReport?: PriceComparisonsReport; priceComparisonsReport?: PriceComparisonsReport;
} }
@@ -519,7 +521,7 @@ export interface MarketSideLiquidity {
export interface RawQuotes { export interface RawQuotes {
nativeOrders: NativeOrderWithFillableAmounts[]; nativeOrders: NativeOrderWithFillableAmounts[];
rfqtIndicativeQuotes: V4RFQIndicativeQuote[]; rfqtIndicativeQuotes: V4RFQIndicativeQuoteMM[];
twoHopQuotes: Array<DexSample<MultiHopFillData>>; twoHopQuotes: Array<DexSample<MultiHopFillData>>;
dexQuotes: Array<Array<DexSample<FillData>>>; dexQuotes: Array<Array<DexSample<FillData>>>;
} }

View File

@@ -14,8 +14,9 @@ import {
NativeFillData, NativeFillData,
NativeLimitOrderFillData, NativeLimitOrderFillData,
NativeRfqOrderFillData, NativeRfqOrderFillData,
RawQuotes,
} from './market_operation_utils/types'; } from './market_operation_utils/types';
import { QuoteRequestor } from './quote_requestor'; import { QuoteRequestor, V4RFQIndicativeQuoteMM } from './quote_requestor';
export interface QuoteReportEntryBase { export interface QuoteReportEntryBase {
liquiditySource: ERC20BridgeSource; liquiditySource: ERC20BridgeSource;
@@ -36,30 +37,77 @@ export interface NativeLimitOrderQuoteReportEntry extends QuoteReportEntryBase {
liquiditySource: ERC20BridgeSource.Native; liquiditySource: ERC20BridgeSource.Native;
fillData: NativeFillData; fillData: NativeFillData;
fillableTakerAmount: BigNumber; fillableTakerAmount: BigNumber;
isRfqt: false; isRFQ: false;
} }
export interface NativeRfqOrderQuoteReportEntry extends QuoteReportEntryBase { export interface NativeRfqOrderQuoteReportEntry extends QuoteReportEntryBase {
liquiditySource: ERC20BridgeSource.Native; liquiditySource: ERC20BridgeSource.Native;
fillData: NativeFillData; fillData: NativeFillData;
fillableTakerAmount: BigNumber; fillableTakerAmount: BigNumber;
isRfqt: true; isRFQ: true;
nativeOrder: RfqOrderFields; nativeOrder: RfqOrderFields;
makerUri: string; makerUri: string;
comparisonPrice?: number; comparisonPrice?: number;
} }
export interface IndicativeRfqOrderQuoteReportEntry extends QuoteReportEntryBase {
liquiditySource: ERC20BridgeSource.Native;
fillableTakerAmount: BigNumber;
isRFQ: true;
makerUri?: string;
comparisonPrice?: number;
}
export type QuoteReportEntry = export type QuoteReportEntry =
| BridgeQuoteReportEntry | BridgeQuoteReportEntry
| MultiHopQuoteReportEntry | MultiHopQuoteReportEntry
| NativeLimitOrderQuoteReportEntry | NativeLimitOrderQuoteReportEntry
| NativeRfqOrderQuoteReportEntry; | NativeRfqOrderQuoteReportEntry;
export type ExtendedQuoteReportEntry =
| BridgeQuoteReportEntry
| MultiHopQuoteReportEntry
| NativeLimitOrderQuoteReportEntry
| NativeRfqOrderQuoteReportEntry
| IndicativeRfqOrderQuoteReportEntry;
export type ExtendedQuoteReportIndexedEntry = ExtendedQuoteReportEntry & {
quoteEntryIndex: number;
isDelivered: boolean;
};
export type ExtendedQuoteReportIndexedEntryOutbound = Omit<ExtendedQuoteReportIndexedEntry, 'fillData'> & {
fillData?: string;
};
export interface QuoteReport { export interface QuoteReport {
sourcesConsidered: QuoteReportEntry[]; sourcesConsidered: QuoteReportEntry[];
sourcesDelivered: QuoteReportEntry[]; sourcesDelivered: QuoteReportEntry[];
} }
export interface ExtendedQuoteReportSources {
sourcesConsidered: ExtendedQuoteReportIndexedEntry[];
sourcesDelivered: ExtendedQuoteReportIndexedEntry[] | undefined;
}
export interface ExtendedQuoteReport {
quoteId?: string;
taker?: string;
timestamp: number;
firmQuoteReport: boolean;
submissionBy: 'taker' | 'metaTxn' | 'rfqm';
buyAmount?: string;
sellAmount?: string;
buyTokenAddress: string;
sellTokenAddress: string;
integratorId?: string;
slippageBips?: number;
zeroExTransactionHash?: string;
decodedUniqueId?: string;
sourcesConsidered: ExtendedQuoteReportIndexedEntryOutbound[];
sourcesDelivered: ExtendedQuoteReportIndexedEntryOutbound[] | undefined;
}
export interface PriceComparisonsReport { export interface PriceComparisonsReport {
dexSources: BridgeQuoteReportEntry[]; dexSources: BridgeQuoteReportEntry[];
multiHopSources: MultiHopQuoteReportEntry[]; multiHopSources: MultiHopQuoteReportEntry[];
@@ -80,7 +128,7 @@ export function generateQuoteReport(
const nativeOrderSourcesConsidered = nativeOrders.map(order => const nativeOrderSourcesConsidered = nativeOrders.map(order =>
nativeOrderToReportEntry(order.type, order as any, order.fillableTakerAmount, comparisonPrice, quoteRequestor), nativeOrderToReportEntry(order.type, order as any, order.fillableTakerAmount, comparisonPrice, quoteRequestor),
); );
const sourcesConsidered = [...nativeOrderSourcesConsidered.filter(order => order.isRfqt)]; const sourcesConsidered = [...nativeOrderSourcesConsidered.filter(order => order.isRFQ)];
let sourcesDelivered; let sourcesDelivered;
if (Array.isArray(liquidityDelivered)) { if (Array.isArray(liquidityDelivered)) {
@@ -116,6 +164,105 @@ export function generateQuoteReport(
}; };
} }
/**
* Generates a report of sources considered while computing the optimized
* swap quote, the sources ultimately included in the computed quote. This
* extende version incudes all considered quotes, not only native liquidity.
*/
export function generateExtendedQuoteReportSources(
marketOperation: MarketOperation,
quotes: RawQuotes,
liquidityDelivered: ReadonlyArray<CollapsedFill> | DexSample<MultiHopFillData>,
amount: BigNumber,
comparisonPrice?: BigNumber | undefined,
quoteRequestor?: QuoteRequestor,
): ExtendedQuoteReportSources {
const sourcesConsidered: ExtendedQuoteReportEntry[] = [];
// NativeOrders
sourcesConsidered.push(
...quotes.nativeOrders.map(order =>
nativeOrderToReportEntry(
order.type,
order as any,
order.fillableTakerAmount,
comparisonPrice,
quoteRequestor,
),
),
);
// IndicativeQuotes
sourcesConsidered.push(
...quotes.rfqtIndicativeQuotes.map(order => indicativeQuoteToReportEntry(order, comparisonPrice)),
);
// MultiHop
sourcesConsidered.push(...quotes.twoHopQuotes.map(quote => multiHopSampleToReportSource(quote, marketOperation)));
// Dex Quotes
sourcesConsidered.push(
..._.flatten(
quotes.dexQuotes.map(dex =>
dex
.filter(quote => isDexSampleForTotalAmount(quote, marketOperation, amount))
.map(quote => dexSampleToReportSource(quote, marketOperation)),
),
),
);
const sourcesConsideredIndexed = sourcesConsidered.map(
(quote, index): ExtendedQuoteReportIndexedEntry => {
return {
...quote,
quoteEntryIndex: index,
isDelivered: false,
};
},
);
let sourcesDelivered;
if (Array.isArray(liquidityDelivered)) {
// create easy way to look up fillable amounts
const nativeOrderSignaturesToFillableAmounts = _.fromPairs(
quotes.nativeOrders.map(o => {
return [_nativeDataToId(o), o.fillableTakerAmount];
}),
);
// map sources delivered
sourcesDelivered = liquidityDelivered.map(collapsedFill => {
if (_isNativeOrderFromCollapsedFill(collapsedFill)) {
return nativeOrderToReportEntry(
collapsedFill.type,
collapsedFill.fillData,
nativeOrderSignaturesToFillableAmounts[_nativeDataToId(collapsedFill.fillData)],
comparisonPrice,
quoteRequestor,
);
} else {
return dexSampleToReportSource(collapsedFill, marketOperation);
}
});
} else {
sourcesDelivered = [
// tslint:disable-next-line: no-unnecessary-type-assertion
multiHopSampleToReportSource(liquidityDelivered as DexSample<MultiHopFillData>, marketOperation),
];
}
const sourcesDeliveredIndexed = sourcesDelivered.map(
(quote, index): ExtendedQuoteReportIndexedEntry => {
return {
...quote,
quoteEntryIndex: index,
isDelivered: false,
};
},
);
return {
sourcesConsidered: sourcesConsideredIndexed,
sourcesDelivered: sourcesDeliveredIndexed,
};
}
function _nativeDataToId(data: { signature: Signature }): string { function _nativeDataToId(data: { signature: Signature }): string {
const { v, r, s } = data.signature; const { v, r, s } = data.signature;
return `${v}${r}${s}`; return `${v}${r}${s}`;
@@ -153,6 +300,22 @@ export function dexSampleToReportSource(ds: DexSample, marketOperation: MarketOp
} }
} }
/**
* Checks if a DEX sample is the one that represents the whole amount requested by taker
* NOTE: this is used for the QuoteReport to filter samples
*/
function isDexSampleForTotalAmount(ds: DexSample, marketOperation: MarketOperation, amount: BigNumber): boolean {
// input and output map to different values
// based on the market operation
if (marketOperation === MarketOperation.Buy) {
return ds.input === amount;
} else if (marketOperation === MarketOperation.Sell) {
return ds.output === amount;
} else {
throw new Error(`Unexpected marketOperation ${marketOperation}`);
}
}
/** /**
* Generates a report sample for a MultiHop source * Generates a report sample for a MultiHop source
* NOTE: this is used for the QuoteReport and quote price comparison data * NOTE: this is used for the QuoteReport and quote price comparison data
@@ -208,17 +371,17 @@ export function nativeOrderToReportEntry(
}; };
// if we find this is an rfqt order, label it as such and associate makerUri // if we find this is an rfqt order, label it as such and associate makerUri
const isRfqt = type === FillQuoteTransformerOrderType.Rfq; const isRFQ = type === FillQuoteTransformerOrderType.Rfq;
const rfqtMakerUri = const rfqtMakerUri =
isRfqt && quoteRequestor ? quoteRequestor.getMakerUriForSignature(fillData.signature) : undefined; isRFQ && quoteRequestor ? quoteRequestor.getMakerUriForSignature(fillData.signature) : undefined;
if (isRfqt) { if (isRFQ) {
const nativeOrder = fillData.order as RfqOrderFields; const nativeOrder = fillData.order as RfqOrderFields;
// tslint:disable-next-line: no-object-literal-type-assertion // tslint:disable-next-line: no-object-literal-type-assertion
return { return {
liquiditySource: ERC20BridgeSource.Native, liquiditySource: ERC20BridgeSource.Native,
...nativeOrderBase, ...nativeOrderBase,
isRfqt: true, isRFQ: true,
makerUri: rfqtMakerUri || '', makerUri: rfqtMakerUri || '',
...(comparisonPrice ? { comparisonPrice: comparisonPrice.toNumber() } : {}), ...(comparisonPrice ? { comparisonPrice: comparisonPrice.toNumber() } : {}),
nativeOrder, nativeOrder,
@@ -229,8 +392,49 @@ export function nativeOrderToReportEntry(
return { return {
liquiditySource: ERC20BridgeSource.Native, liquiditySource: ERC20BridgeSource.Native,
...nativeOrderBase, ...nativeOrderBase,
isRfqt: false, isRFQ: false,
fillData, fillData,
}; };
} }
} }
/**
* Generates a report entry for an indicative RFQ Quote
* NOTE: this is used for the QuoteReport and quote price comparison data
*/
export function indicativeQuoteToReportEntry(
order: V4RFQIndicativeQuoteMM,
comparisonPrice?: BigNumber | undefined,
): IndicativeRfqOrderQuoteReportEntry {
const nativeOrderBase = {
makerAmount: order.makerAmount,
takerAmount: order.takerAmount,
fillableTakerAmount: order.takerAmount,
};
// tslint:disable-next-line: no-object-literal-type-assertion
return {
liquiditySource: ERC20BridgeSource.Native,
...nativeOrderBase,
isRFQ: true,
makerUri: order.makerUri,
fillData: {},
...(comparisonPrice ? { comparisonPrice: comparisonPrice.toNumber() } : {}),
};
}
/**
* For the extended quote report, we output the filldata as JSON
*/
export function jsonifyFillData(source: ExtendedQuoteReportIndexedEntry): ExtendedQuoteReportIndexedEntryOutbound {
return {
...source,
fillData: JSON.stringify(source.fillData, (key: string, value: any) => {
if (key === '_samplerContract') {
return {};
} else {
return value;
}
}),
};
}

View File

@@ -39,6 +39,10 @@ interface RfqQuote<T> {
makerUri: string; makerUri: string;
} }
export interface V4RFQIndicativeQuoteMM extends V4RFQIndicativeQuote {
makerUri: string;
}
export interface MetricsProxy { export interface MetricsProxy {
/** /**
* Increments a counter that is tracking valid Firm Quotes that are dropped due to low expiration. * Increments a counter that is tracking valid Firm Quotes that are dropped due to low expiration.
@@ -343,7 +347,7 @@ export class QuoteRequestor {
marketOperation: MarketOperation, marketOperation: MarketOperation,
comparisonPrice: BigNumber | undefined, comparisonPrice: BigNumber | undefined,
options: RfqmRequestOptions, options: RfqmRequestOptions,
): Promise<V4RFQIndicativeQuote[]> { ): Promise<V4RFQIndicativeQuoteMM[]> {
const _opts: RfqRequestOpts = { const _opts: RfqRequestOpts = {
...constants.DEFAULT_RFQT_REQUEST_OPTS, ...constants.DEFAULT_RFQT_REQUEST_OPTS,
...options, ...options,
@@ -367,7 +371,7 @@ export class QuoteRequestor {
marketOperation: MarketOperation, marketOperation: MarketOperation,
comparisonPrice: BigNumber | undefined, comparisonPrice: BigNumber | undefined,
options: RfqRequestOpts, options: RfqRequestOpts,
): Promise<V4RFQIndicativeQuote[]> { ): Promise<V4RFQIndicativeQuoteMM[]> {
const _opts: RfqRequestOpts = { ...constants.DEFAULT_RFQT_REQUEST_OPTS, ...options }; const _opts: RfqRequestOpts = { ...constants.DEFAULT_RFQT_REQUEST_OPTS, ...options };
// Originally a takerAddress was required for indicative quotes, but // Originally a takerAddress was required for indicative quotes, but
// now we've eliminated that requirement. @0x/quote-server, however, // now we've eliminated that requirement. @0x/quote-server, however,
@@ -398,8 +402,8 @@ export class QuoteRequestor {
return this._orderSignatureToMakerUri[nativeDataToId({ signature })]; return this._orderSignatureToMakerUri[nativeDataToId({ signature })];
} }
private _isValidRfqtIndicativeQuoteResponse(response: V4RFQIndicativeQuote): boolean { private _isValidRfqtIndicativeQuoteResponse(response: V4RFQIndicativeQuoteMM): boolean {
const requiredKeys: Array<keyof V4RFQIndicativeQuote> = [ const requiredKeys: Array<keyof V4RFQIndicativeQuoteMM> = [
'makerAmount', 'makerAmount',
'takerAmount', 'takerAmount',
'makerToken', 'makerToken',
@@ -545,7 +549,10 @@ export class QuoteRequestor {
}, },
}); });
rfqMakerBlacklist.logTimeoutOrLackThereof(typedMakerUrl.url, latencyMs >= timeoutMs); rfqMakerBlacklist.logTimeoutOrLackThereof(typedMakerUrl.url, latencyMs >= timeoutMs);
return { response: response.data, makerUri: typedMakerUrl.url }; return {
response: { ...response.data, makerUri: typedMakerUrl.url },
makerUri: typedMakerUrl.url,
};
} else { } else {
if (this._altRfqCreds === undefined) { if (this._altRfqCreds === undefined) {
throw new Error(`don't have credentials for alt MM`); throw new Error(`don't have credentials for alt MM`);
@@ -694,7 +701,6 @@ export class QuoteRequestor {
} else { } else {
const secondsRemaining = msRemainingUntilExpiration.div(ONE_SECOND_MS); const secondsRemaining = msRemainingUntilExpiration.div(ONE_SECOND_MS);
this._metrics?.measureExpirationForValidOrder(isLastLook, order.maker, secondsRemaining); this._metrics?.measureExpirationForValidOrder(isLastLook, order.maker, secondsRemaining);
const takerAmount = new BigNumber(order.takerAmount); const takerAmount = new BigNumber(order.takerAmount);
const fillRatio = takerAmount.div(assetFillAmount); const fillRatio = takerAmount.div(assetFillAmount);
if (fillRatio.lt(1) && fillRatio.gte(FILL_RATIO_WARNING_LEVEL)) { if (fillRatio.lt(1) && fillRatio.gte(FILL_RATIO_WARNING_LEVEL)) {
@@ -744,9 +750,9 @@ export class QuoteRequestor {
comparisonPrice: BigNumber | undefined, comparisonPrice: BigNumber | undefined,
options: RfqRequestOpts, options: RfqRequestOpts,
assetOfferings: RfqMakerAssetOfferings, assetOfferings: RfqMakerAssetOfferings,
): Promise<V4RFQIndicativeQuote[]> { ): Promise<V4RFQIndicativeQuoteMM[]> {
// fetch quotes // fetch quotes
const rawQuotes = await this._getQuotesAsync<V4RFQIndicativeQuote>( const rawQuotes = await this._getQuotesAsync<V4RFQIndicativeQuoteMM>(
makerToken, makerToken,
takerToken, takerToken,
assetFillAmount, assetFillAmount,
@@ -758,7 +764,7 @@ export class QuoteRequestor {
); );
// validate // validate
const validationFunction = (o: V4RFQIndicativeQuote) => this._isValidRfqtIndicativeQuoteResponse(o); const validationFunction = (o: V4RFQIndicativeQuoteMM) => this._isValidRfqtIndicativeQuoteResponse(o);
const validQuotes = rawQuotes.filter(result => { const validQuotes = rawQuotes.filter(result => {
const order = result.response; const order = result.response;
if (!validationFunction(order)) { if (!validationFunction(order)) {

View File

@@ -159,7 +159,11 @@ describe('MarketOperationUtils tests', () => {
} else { } else {
requestor requestor
.setup(r => r.requestRfqtIndicativeQuotesAsync(...args)) .setup(r => r.requestRfqtIndicativeQuotesAsync(...args))
.returns(async () => results.map(r => r.order)) .returns(async () =>
results.map(r => {
return { ...r.order, makerUri: 'https://foo.bar/' };
}),
)
.verifiable(verifiable); .verifiable(verifiable);
} }
return requestor; return requestor;

View File

@@ -155,7 +155,7 @@ describe('generateQuoteReport', async () => {
makerAmount: rfqtOrder1.order.makerAmount, makerAmount: rfqtOrder1.order.makerAmount,
takerAmount: rfqtOrder1.order.takerAmount, takerAmount: rfqtOrder1.order.takerAmount,
fillableTakerAmount: rfqtOrder1.fillableTakerAmount, fillableTakerAmount: rfqtOrder1.fillableTakerAmount,
isRfqt: true, isRFQ: true,
makerUri: 'https://rfqt1.provider.club', makerUri: 'https://rfqt1.provider.club',
nativeOrder: rfqtOrder1.order, nativeOrder: rfqtOrder1.order,
fillData: { fillData: {
@@ -167,7 +167,7 @@ describe('generateQuoteReport', async () => {
makerAmount: rfqtOrder2.order.makerAmount, makerAmount: rfqtOrder2.order.makerAmount,
takerAmount: rfqtOrder2.order.takerAmount, takerAmount: rfqtOrder2.order.takerAmount,
fillableTakerAmount: rfqtOrder2.fillableTakerAmount, fillableTakerAmount: rfqtOrder2.fillableTakerAmount,
isRfqt: true, isRFQ: true,
makerUri: 'https://rfqt2.provider.club', makerUri: 'https://rfqt2.provider.club',
nativeOrder: rfqtOrder2.order, nativeOrder: rfqtOrder2.order,
fillData: { fillData: {
@@ -179,7 +179,7 @@ describe('generateQuoteReport', async () => {
makerAmount: orderbookOrder2.order.makerAmount, makerAmount: orderbookOrder2.order.makerAmount,
takerAmount: orderbookOrder2.order.takerAmount, takerAmount: orderbookOrder2.order.takerAmount,
fillableTakerAmount: orderbookOrder2.fillableTakerAmount, fillableTakerAmount: orderbookOrder2.fillableTakerAmount,
isRfqt: false, isRFQ: false,
fillData: { fillData: {
order: orderbookOrder2.order, order: orderbookOrder2.order,
} as NativeLimitOrderFillData, } as NativeLimitOrderFillData,
@@ -263,7 +263,7 @@ describe('generateQuoteReport', async () => {
makerAmount: orderbookOrder1.order.makerAmount, makerAmount: orderbookOrder1.order.makerAmount,
takerAmount: orderbookOrder1.order.takerAmount, takerAmount: orderbookOrder1.order.takerAmount,
fillableTakerAmount: orderbookOrder1.fillableTakerAmount, fillableTakerAmount: orderbookOrder1.fillableTakerAmount,
isRfqt: false, isRFQ: false,
fillData: { fillData: {
order: orderbookOrder1.order, order: orderbookOrder1.order,
} as NativeLimitOrderFillData, } as NativeLimitOrderFillData,

View File

@@ -494,15 +494,18 @@ describe('QuoteRequestor', async () => {
expiry: makeThreeMinuteExpiry(), expiry: makeThreeMinuteExpiry(),
}; };
const goodMMUri1 = 'https://1337.0.0.1';
const goodMMUri2 = 'https://37.0.0.1';
mockedRequests.push({ mockedRequests.push({
...mockedDefaults, ...mockedDefaults,
endpoint: 'https://1337.0.0.1', endpoint: goodMMUri1,
responseData: successfulQuote1, responseData: successfulQuote1,
}); });
// [GOOD] Another Successful response // [GOOD] Another Successful response
mockedRequests.push({ mockedRequests.push({
...mockedDefaults, ...mockedDefaults,
endpoint: 'https://37.0.0.1', endpoint: goodMMUri2,
responseData: successfulQuote1, responseData: successfulQuote1,
}); });
@@ -532,6 +535,16 @@ describe('QuoteRequestor', async () => {
responseData: { ...successfulQuote1, takerToken: otherToken1 }, responseData: { ...successfulQuote1, takerToken: otherToken1 },
}); });
const assetOfferings: { [k: string]: [[string, string]] } = {
'https://420.0.0.1': [[makerToken, takerToken]],
'https://421.0.0.1': [[makerToken, takerToken]],
'https://422.0.0.1': [[makerToken, takerToken]],
'https://423.0.0.1': [[makerToken, takerToken]],
'https://424.0.0.1': [[makerToken, takerToken]],
};
assetOfferings[goodMMUri1] = [[makerToken, takerToken]];
assetOfferings[goodMMUri2] = [[makerToken, takerToken]];
return testHelpers.withMockedRfqQuotes( return testHelpers.withMockedRfqQuotes(
mockedRequests, mockedRequests,
[], [],
@@ -539,15 +552,7 @@ describe('QuoteRequestor', async () => {
async () => { async () => {
const qr = new QuoteRequestor( const qr = new QuoteRequestor(
{}, // No RFQ-T asset offerings {}, // No RFQ-T asset offerings
{ assetOfferings,
'https://1337.0.0.1': [[makerToken, takerToken]],
'https://37.0.0.1': [[makerToken, takerToken]],
'https://420.0.0.1': [[makerToken, takerToken]],
'https://421.0.0.1': [[makerToken, takerToken]],
'https://422.0.0.1': [[makerToken, takerToken]],
'https://423.0.0.1': [[makerToken, takerToken]],
'https://424.0.0.1': [[makerToken, takerToken]],
},
quoteRequestorHttpClient, quoteRequestorHttpClient,
); );
const resp = await qr.requestRfqmIndicativeQuotesAsync( const resp = await qr.requestRfqmIndicativeQuotesAsync(
@@ -572,7 +577,12 @@ describe('QuoteRequestor', async () => {
}, },
}, },
); );
expect(resp.sort()).to.eql([successfulQuote1, successfulQuote1].sort()); expect(resp.sort()).to.eql(
[
{ ...successfulQuote1, makerUri: goodMMUri1 },
{ ...successfulQuote1, makerUri: goodMMUri2 },
].sort(),
);
}, },
quoteRequestorHttpClient, quoteRequestorHttpClient,
); );
@@ -622,9 +632,12 @@ describe('QuoteRequestor', async () => {
expiry: makeThreeMinuteExpiry(), expiry: makeThreeMinuteExpiry(),
}; };
const goodMMUri1 = 'https://1337.0.0.1';
const goodMMUri2 = 'https://37.0.0.1';
mockedRequests.push({ mockedRequests.push({
...mockedDefaults, ...mockedDefaults,
endpoint: 'https://1337.0.0.1', endpoint: goodMMUri1,
responseData: successfulQuote1, responseData: successfulQuote1,
}); });
// Test out a bad response code, ensure it doesnt cause throw // Test out a bad response code, ensure it doesnt cause throw
@@ -655,28 +668,26 @@ describe('QuoteRequestor', async () => {
// Another Successful response // Another Successful response
mockedRequests.push({ mockedRequests.push({
...mockedDefaults, ...mockedDefaults,
endpoint: 'https://37.0.0.1', endpoint: goodMMUri2,
responseData: successfulQuote1, responseData: successfulQuote1,
}); });
const assetOfferings: { [k: string]: [[string, string]] } = {
'https://420.0.0.1': [[makerToken, takerToken]],
'https://421.0.0.1': [[makerToken, takerToken]],
'https://422.0.0.1': [[makerToken, takerToken]],
'https://423.0.0.1': [[makerToken, takerToken]],
'https://424.0.0.1': [[makerToken, takerToken]],
};
assetOfferings[goodMMUri1] = [[makerToken, takerToken]];
assetOfferings[goodMMUri2] = [[makerToken, takerToken]];
return testHelpers.withMockedRfqQuotes( return testHelpers.withMockedRfqQuotes(
mockedRequests, mockedRequests,
[], [],
RfqQuoteEndpoint.Indicative, RfqQuoteEndpoint.Indicative,
async () => { async () => {
const qr = new QuoteRequestor( const qr = new QuoteRequestor(assetOfferings, {}, quoteRequestorHttpClient);
{
'https://1337.0.0.1': [[makerToken, takerToken]],
'https://420.0.0.1': [[makerToken, takerToken]],
'https://421.0.0.1': [[makerToken, takerToken]],
'https://422.0.0.1': [[makerToken, takerToken]],
'https://423.0.0.1': [[makerToken, takerToken]],
'https://424.0.0.1': [[makerToken, takerToken]],
'https://37.0.0.1': [[makerToken, takerToken]],
},
{},
quoteRequestorHttpClient,
);
const resp = await qr.requestRfqtIndicativeQuotesAsync( const resp = await qr.requestRfqtIndicativeQuotesAsync(
makerToken, makerToken,
takerToken, takerToken,
@@ -693,7 +704,12 @@ describe('QuoteRequestor', async () => {
intentOnFilling: true, intentOnFilling: true,
}, },
); );
expect(resp.sort()).to.eql([successfulQuote1, successfulQuote1].sort()); expect(resp.sort()).to.eql(
[
{ ...successfulQuote1, makerUri: goodMMUri1 },
{ ...successfulQuote1, makerUri: goodMMUri2 },
].sort(),
);
}, },
quoteRequestorHttpClient, quoteRequestorHttpClient,
); );
@@ -784,7 +800,7 @@ describe('QuoteRequestor', async () => {
makerEndpointMaxResponseTimeMs: maxTimeoutMs, makerEndpointMaxResponseTimeMs: maxTimeoutMs,
}, },
); );
expect(resp.sort()).to.eql([successfulQuote1].sort()); // notice only one result, despite two requests made expect(resp.sort()).to.eql([{ ...successfulQuote1, makerUri: 'https://1337.0.0.1' }].sort()); // notice only one result, despite two requests made
}, },
quoteRequestorHttpClient, quoteRequestorHttpClient,
); );
@@ -847,7 +863,7 @@ describe('QuoteRequestor', async () => {
intentOnFilling: true, intentOnFilling: true,
}, },
); );
expect(resp.sort()).to.eql([successfulQuote1].sort()); expect(resp.sort()).to.eql([{ ...successfulQuote1, makerUri: 'https://1337.0.0.1' }].sort());
}, },
quoteRequestorHttpClient, quoteRequestorHttpClient,
); );

View File

@@ -1,4 +1,14 @@
[ [
{
"version": "6.9.0",
"changes": [
{
"note": "Add Celo addresses",
"pr": 368
}
],
"timestamp": 1637102971
},
{ {
"timestamp": 1635903615, "timestamp": 1635903615,
"version": "6.8.1", "version": "6.8.1",

View File

@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v6.9.0 - _November 16, 2021_
* Add Celo addresses (#368)
## v6.8.1 - _November 3, 2021_ ## v6.8.1 - _November 3, 2021_
* Dependencies updated * Dependencies updated

View File

@@ -418,5 +418,47 @@
"fillQuoteTransformer": "0x71de60a1b160094a3f6c7e1b883ff9337d639131", "fillQuoteTransformer": "0x71de60a1b160094a3f6c7e1b883ff9337d639131",
"positiveSlippageFeeTransformer": "0xe87d69b285005cc82b53b844322652c49ed64600" "positiveSlippageFeeTransformer": "0xe87d69b285005cc82b53b844322652c49ed64600"
} }
},
"42220": {
"erc20Proxy": "0x0000000000000000000000000000000000000000",
"erc721Proxy": "0x0000000000000000000000000000000000000000",
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0x471ece3750da237f93b8e339c536989b8978a438",
"exchangeV2": "0x0000000000000000000000000000000000000000",
"exchange": "0x0000000000000000000000000000000000000000",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"forwarder": "0x0000000000000000000000000000000000000000",
"coordinatorRegistry": "0x0000000000000000000000000000000000000000",
"coordinator": "0x0000000000000000000000000000000000000000",
"multiAssetProxy": "0x0000000000000000000000000000000000000000",
"staticCallProxy": "0x0000000000000000000000000000000000000000",
"erc1155Proxy": "0x0000000000000000000000000000000000000000",
"devUtils": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0x0000000000000000000000000000000000000000",
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0x92115010fd9b170d4918b102efc86b1b7bebdc7f",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0x1fe80d5ad9464dba2d60b88e449305f184823f8a",
"exchangeProxyFlashWallet": "0xdb6f1920a889355780af7570773609bd8cb1f498",
"exchangeProxyLiquidityProviderSandbox": "0x0000000000000000000000000000000000000000",
"zrxTreasury": "0x0000000000000000000000000000000000000000",
"transformers": {
"wethTransformer": "0x948e03e708b4c62c63f89157a3aa76b986c110ed",
"payTakerTransformer": "0x90fb6c638ece8f3e4bfda1c6d6425626b53148b0",
"affiliateFeeTransformer": "0xc93913692ed073cb0cb37d4a760afd7916e9cb01",
"fillQuoteTransformer": "0xa825d4d3c4d2820c52da69fcccf269b4081871f2",
"positiveSlippageFeeTransformer": "0x9ffc7a79133ed5242777e40764777a6d5aab282c"
}
} }
} }

View File

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

View File

@@ -54,6 +54,7 @@ export enum ChainId {
PolygonMumbai = 80001, PolygonMumbai = 80001,
Avalanche = 43114, Avalanche = 43114,
Fantom = 250, Fantom = 250,
Celo = 42220,
} }
/** /**

View File

@@ -1,4 +1,13 @@
[ [
{
"timestamp": 1637102971,
"version": "13.18.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1635903615, "timestamp": 1635903615,
"version": "13.18.2", "version": "13.18.2",

View File

@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v13.18.3 - _November 16, 2021_
* Dependencies updated
## v13.18.2 - _November 3, 2021_ ## v13.18.2 - _November 3, 2021_
* Dependencies updated * Dependencies updated

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contract-wrappers", "name": "@0x/contract-wrappers",
"version": "13.18.2", "version": "13.18.3",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -57,7 +57,7 @@
"dependencies": { "dependencies": {
"@0x/assert": "^3.0.29", "@0x/assert": "^3.0.29",
"@0x/base-contract": "^6.4.2", "@0x/base-contract": "^6.4.2",
"@0x/contract-addresses": "^6.8.1", "@0x/contract-addresses": "^6.9.0",
"@0x/json-schemas": "^6.3.0", "@0x/json-schemas": "^6.3.0",
"@0x/types": "^3.3.4", "@0x/types": "^3.3.4",
"@0x/utils": "^6.4.4", "@0x/utils": "^6.4.4",

View File

@@ -1,4 +1,22 @@
[ [
{
"timestamp": 1637102971,
"version": "8.1.12",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1637065617,
"version": "8.1.11",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"version": "8.1.10", "version": "8.1.10",
"changes": [ "changes": [

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v8.1.12 - _November 16, 2021_
* Dependencies updated
## v8.1.11 - _November 16, 2021_
* Dependencies updated
## v8.1.10 - _November 3, 2021_ ## v8.1.10 - _November 3, 2021_
* Add OtcOrders to fullMigrateAsync (#350) * Add OtcOrders to fullMigrateAsync (#350)

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/migrations", "name": "@0x/migrations",
"version": "8.1.10", "version": "8.1.12",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -68,20 +68,20 @@
}, },
"dependencies": { "dependencies": {
"@0x/base-contract": "^6.4.2", "@0x/base-contract": "^6.4.2",
"@0x/contract-addresses": "^6.8.1", "@0x/contract-addresses": "^6.9.0",
"@0x/contracts-asset-proxy": "^3.7.19", "@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-coordinator": "^3.1.38", "@0x/contracts-coordinator": "^3.1.38",
"@0x/contracts-dev-utils": "^1.3.36", "@0x/contracts-dev-utils": "^1.3.36",
"@0x/contracts-erc1155": "^2.1.37", "@0x/contracts-erc1155": "^2.1.37",
"@0x/contracts-erc20": "^3.3.22", "@0x/contracts-erc20": "^3.3.23",
"@0x/contracts-erc721": "^3.1.37", "@0x/contracts-erc721": "^3.1.37",
"@0x/contracts-exchange": "^3.2.38", "@0x/contracts-exchange": "^3.2.38",
"@0x/contracts-exchange-forwarder": "^4.2.38", "@0x/contracts-exchange-forwarder": "^4.2.38",
"@0x/contracts-extensions": "^6.2.32", "@0x/contracts-extensions": "^6.2.32",
"@0x/contracts-multisig": "^4.1.38", "@0x/contracts-multisig": "^4.1.38",
"@0x/contracts-staking": "^2.0.45", "@0x/contracts-staking": "^2.0.45",
"@0x/contracts-utils": "^4.8.3", "@0x/contracts-utils": "^4.8.4",
"@0x/contracts-zero-ex": "^0.29.3", "@0x/contracts-zero-ex": "^0.29.5",
"@0x/sol-compiler": "^4.7.5", "@0x/sol-compiler": "^4.7.5",
"@0x/subproviders": "^6.6.0", "@0x/subproviders": "^6.6.0",
"@0x/typescript-typings": "^5.2.1", "@0x/typescript-typings": "^5.2.1",

View File

@@ -1,4 +1,13 @@
[ [
{
"timestamp": 1637102971,
"version": "1.9.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1635903615, "timestamp": 1635903615,
"version": "1.9.4", "version": "1.9.4",

View File

@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.9.5 - _November 16, 2021_
* Dependencies updated
## v1.9.4 - _November 3, 2021_ ## v1.9.4 - _November 3, 2021_
* Dependencies updated * Dependencies updated

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/protocol-utils", "name": "@0x/protocol-utils",
"version": "1.9.4", "version": "1.9.5",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -63,8 +63,8 @@
}, },
"dependencies": { "dependencies": {
"@0x/assert": "^3.0.29", "@0x/assert": "^3.0.29",
"@0x/contract-addresses": "^6.8.1", "@0x/contract-addresses": "^6.9.0",
"@0x/contract-wrappers": "^13.18.2", "@0x/contract-wrappers": "^13.18.3",
"@0x/json-schemas": "^6.3.0", "@0x/json-schemas": "^6.3.0",
"@0x/subproviders": "^6.6.0", "@0x/subproviders": "^6.6.0",
"@0x/utils": "^6.4.4", "@0x/utils": "^6.4.4",

View File

@@ -6402,6 +6402,7 @@ fake-merkle-patricia-tree@^1.0.1:
fast-abi@^0.0.2: fast-abi@^0.0.2:
version "0.0.2" version "0.0.2"
resolved "https://registry.yarnpkg.com/fast-abi/-/fast-abi-0.0.2.tgz#da5f796fd7c7b0c966d916ee21daae3eca61c07c" resolved "https://registry.yarnpkg.com/fast-abi/-/fast-abi-0.0.2.tgz#da5f796fd7c7b0c966d916ee21daae3eca61c07c"
integrity sha512-k/2s63SkFf6jU2LyF6oQC5/N+L90q6VD1wkp2NXo+DSHoTeOJD2Q6Egpcs+bTPODik0CHxjb7lORgsG+QCRq/Q==
dependencies: dependencies:
"@mapbox/node-pre-gyp" "^1.0.4" "@mapbox/node-pre-gyp" "^1.0.4"
neon-cli "^0.8.0" neon-cli "^0.8.0"