From 5ca7169ee524a2f4b82e06d717680a296428f420 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Thu, 12 Dec 2019 21:03:02 -0800 Subject: [PATCH] Reverted to version of dydx bridge that only allows `from` to be the account owner --- .../contracts/src/bridges/DydxBridge.sol | 154 +++++++---- .../contracts/src/interfaces/IDydxBridge.sol | 16 +- contracts/asset-proxy/src/index.ts | 1 + contracts/asset-proxy/test/dydx_bridge.ts | 258 +++++++++++------- yarn.lock | 185 +------------ 5 files changed, 293 insertions(+), 321 deletions(-) diff --git a/contracts/asset-proxy/contracts/src/bridges/DydxBridge.sol b/contracts/asset-proxy/contracts/src/bridges/DydxBridge.sol index d64075b3eb..624008157a 100644 --- a/contracts/asset-proxy/contracts/src/bridges/DydxBridge.sol +++ b/contracts/asset-proxy/contracts/src/bridges/DydxBridge.sol @@ -20,6 +20,7 @@ pragma solidity ^0.5.9; pragma experimental ABIEncoderV2; import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; +import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; import "../interfaces/IERC20Bridge.sol"; import "../interfaces/IDydxBridge.sol"; import "../interfaces/IDydx.sol"; @@ -31,16 +32,16 @@ contract DydxBridge is DeploymentConstants { + using LibSafeMath for uint256; + /// @dev Callback for `IERC20Bridge`. Deposits or withdraws tokens from a dydx account. /// Notes: /// 1. This bridge must be set as an operator of the input dydx account. /// 2. This function may only be called in the context of the 0x Exchange. - /// 3. The maker of the 0x order must be the dydx account owner. - /// 4. To deposit into dydx use this function in the `takerAssetData`. - /// (The `to` address is the 0x order maker and dydx account owner). - /// 5. To withdraw from dydx use this function in the `makerAssetData`. - /// (The `from` address is the 0x order maker and dydx account owner). - /// @param from The sender of the tokens. + /// 3. The maker or taker of the 0x order must be the dydx account owner. + /// 4. Deposits into dydx are made from the `from` address. + /// 5. Withdrawals from dydx are made to the `to` address. + /// @param from The sender of the tokens and owner of the dydx account. /// @param to The recipient of the tokens. /// @param amount Minimum amount of `toTokenAddress` tokens to deposit or withdraw. /// @param encodedBridgeData An abi-encoded `BridgeData` struct. @@ -64,59 +65,108 @@ contract DydxBridge is // Decode bridge data. (BridgeData memory bridgeData) = abi.decode(encodedBridgeData, (BridgeData)); - // Cache dydx contract. - IDydx dydx = IDydx(_getDydxAddress()); + // The dydx accounts are owned by the `from` address. + IDydx.AccountInfo[] memory accounts = _createAccounts(from, bridgeData); - // Create dydx action. - IDydx.AccountInfo[] memory accounts = new IDydx.AccountInfo[](1); - IDydx.ActionArgs[] memory actions = new IDydx.ActionArgs[](1); - if (bridgeData.action == BridgeAction.Deposit) { - // We interpret `to` as the 0x order maker and `from` as the taker. - accounts[0] = IDydx.AccountInfo({ - owner: to, - number: bridgeData.accountNumber - }); - - // Deposit tokens from the `to` address into their dydx account. - actions[0] = _createDepositAction( - to, - amount, - bridgeData - ); - } else if (bridgeData.action == BridgeAction.Withdraw) { - // We interpret `from` as the 0x order maker and `to` as the taker. - accounts[0] = IDydx.AccountInfo({ - owner: from, - number: bridgeData.accountNumber - }); - - // Withdraw tokens from dydx account owned by `from` into the `to` address. - actions[0] = _createWithdrawAction( - to, - amount, - bridgeData - ); - } else { - // If all values in the `Action` enum are handled then this - // revert is unreachable: Solidity will revert when casting - // from `uint8` to `Action`. - revert("DydxBridge/UNRECOGNIZED_BRIDGE_ACTION"); - } + // Create dydx actions to run on the dydx accounts. + IDydx.ActionArgs[] memory actions = _createActions( + from, + to, + amount, + bridgeData + ); // Run operation. This will revert on failure. - dydx.operate(accounts, actions); + IDydx(_getDydxAddress()).operate(accounts, actions); return BRIDGE_SUCCESS; } + /// @dev Creates an array of accounts for dydx to operate on. + /// All accounts must belong to the same owner. + /// @param accountOwner Owner of the dydx account. + /// @param bridgeData A `BridgeData` struct. + function _createAccounts( + address accountOwner, + BridgeData memory bridgeData + ) + internal + returns (IDydx.AccountInfo[] memory accounts) + { + uint256[] memory accountNumbers = bridgeData.accountNumbers; + uint256 nAccounts = accountNumbers.length; + accounts = new IDydx.AccountInfo[](nAccounts); + for (uint256 i = 0; i < nAccounts; ++i) { + accounts[i] = IDydx.AccountInfo({ + owner: accountOwner, + number: accountNumbers[i] + }); + } + } + + /// @dev Creates an array of actions to carry out on dydx. + /// @param depositFrom Deposit value from this address (owner of the dydx account). + /// @param withdrawTo Withdraw value to this address. + /// @param amount The amount of value available to operate on. + /// @param bridgeData A `BridgeData` struct. + function _createActions( + address depositFrom, + address withdrawTo, + uint256 amount, + BridgeData memory bridgeData + ) + internal + returns (IDydx.ActionArgs[] memory actions) + { + BridgeAction[] memory bridgeActions = bridgeData.actions; + uint256 nBridgeActions = bridgeActions.length; + actions = new IDydx.ActionArgs[](nBridgeActions); + for (uint256 i = 0; i < nBridgeActions; ++i) { + // Cache current bridge action. + BridgeAction memory bridgeAction = bridgeActions[i]; + + // Scale amount, if conversion rate is set. + uint256 scaledAmount; + if (bridgeAction.conversionRateDenominator > 0) { + scaledAmount = amount + .safeMul(bridgeAction.conversionRateNumerator) + .safeDiv(bridgeAction.conversionRateDenominator); + } else { + scaledAmount = amount; + } + + // Construct dydx action. + if (bridgeAction.actionType == BridgeActionType.Deposit) { + // Deposit tokens from the account owner into their dydx account. + actions[i] = _createDepositAction( + depositFrom, + scaledAmount, + bridgeAction + ); + } else if (bridgeAction.actionType == BridgeActionType.Withdraw) { + // Withdraw tokens from dydx to the `otherAccount`. + actions[i] = _createWithdrawAction( + withdrawTo, + scaledAmount, + bridgeAction + ); + } else { + // If all values in the `Action` enum are handled then this + // revert is unreachable: Solidity will revert when casting + // from `uint8` to `Action`. + revert("DydxBridge/UNRECOGNIZED_BRIDGE_ACTION"); + } + } + } + /// @dev Returns a dydx `DepositAction`. /// @param depositFrom Deposit tokens from this address who is also the account owner. /// @param amount of tokens to deposit. - /// @param bridgeData A `BridgeData` struct. + /// @param bridgeAction A `BridgeAction` struct. /// @return depositAction The encoded dydx action. function _createDepositAction( address depositFrom, uint256 amount, - BridgeData memory bridgeData + BridgeAction memory bridgeAction ) internal pure @@ -136,8 +186,8 @@ contract DydxBridge is depositAction = IDydx.ActionArgs({ actionType: IDydx.ActionType.Deposit, // deposit tokens. amount: dydxAmount, // amount to deposit. - accountId: 0, // index in the `accounts` when calling `operate`. - primaryMarketId: bridgeData.marketId, // indicates which token to deposit. + accountId: bridgeAction.accountId, // index in the `accounts` when calling `operate`. + primaryMarketId: bridgeAction.marketId, // indicates which token to deposit. otherAddress: depositFrom, // deposit from the account owner. // unused parameters secondaryMarketId: 0, @@ -149,12 +199,12 @@ contract DydxBridge is /// @dev Returns a dydx `WithdrawAction`. /// @param withdrawTo Withdraw tokens to this address. /// @param amount of tokens to withdraw. - /// @param bridgeData A `BridgeData` struct. + /// @param bridgeAction A `BridgeAction` struct. /// @return withdrawAction The encoded dydx action. function _createWithdrawAction( address withdrawTo, uint256 amount, - BridgeData memory bridgeData + BridgeAction memory bridgeAction ) internal pure @@ -174,8 +224,8 @@ contract DydxBridge is withdrawAction = IDydx.ActionArgs({ actionType: IDydx.ActionType.Withdraw, // withdraw tokens. amount: amountToWithdraw, // amount to withdraw. - accountId: 0, // index in the `accounts` when calling `operate`. - primaryMarketId: bridgeData.marketId, // indicates which token to withdraw. + accountId: bridgeAction.accountId, // index in the `accounts` when calling `operate`. + primaryMarketId: bridgeAction.marketId, // indicates which token to withdraw. otherAddress: withdrawTo, // withdraw tokens to this address. // unused parameters secondaryMarketId: 0, diff --git a/contracts/asset-proxy/contracts/src/interfaces/IDydxBridge.sol b/contracts/asset-proxy/contracts/src/interfaces/IDydxBridge.sol index 29e54a7a70..1b69179f49 100644 --- a/contracts/asset-proxy/contracts/src/interfaces/IDydxBridge.sol +++ b/contracts/asset-proxy/contracts/src/interfaces/IDydxBridge.sol @@ -21,14 +21,22 @@ pragma solidity ^0.5.9; interface IDydxBridge { - enum BridgeAction { + /// @dev This is the subset of `IDydx.ActionType` that are supported by the bridge. + enum BridgeActionType { Deposit, // Deposit tokens into dydx account. Withdraw // Withdraw tokens from dydx account. } + struct BridgeAction { + BridgeActionType actionType; // Action to run on dydx account. + uint256 accountId; // Index in `BridgeData.accountNumbers` for this action. + uint256 marketId; // Market to operate on. + uint256 conversionRateNumerator; // Optional. If set, transfer amount is scaled by (conversionRateNumerator/conversionRateDenominator). + uint256 conversionRateDenominator; // Optional. If set, transfer amount is scaled by (conversionRateNumerator/conversionRateDenominator). + } + struct BridgeData { - BridgeAction action; // Action to run on dydx account. - uint256 accountNumber; // Account number used to identify the owner's specific account. - uint256 marketId; // Market to operate on. + uint256[] accountNumbers; // Account number used to identify the owner's specific account. + BridgeAction[] actions; // Actions to carry out on the owner's accounts. } } \ No newline at end of file diff --git a/contracts/asset-proxy/src/index.ts b/contracts/asset-proxy/src/index.ts index 76e68906e6..4f3be70cd9 100644 --- a/contracts/asset-proxy/src/index.ts +++ b/contracts/asset-proxy/src/index.ts @@ -5,6 +5,7 @@ export { ERC20ProxyContract, ERC721ProxyContract, Eth2DaiBridgeContract, + DydxBridgeContract, IAssetDataContract, IAssetProxyContract, MultiAssetProxyContract, diff --git a/contracts/asset-proxy/test/dydx_bridge.ts b/contracts/asset-proxy/test/dydx_bridge.ts index 19e74cdef6..e148bf9617 100644 --- a/contracts/asset-proxy/test/dydx_bridge.ts +++ b/contracts/asset-proxy/test/dydx_bridge.ts @@ -7,8 +7,9 @@ import { artifacts } from './artifacts'; import { TestDydxBridgeContract, TestDydxBridgeEvents } from './wrappers'; blockchainTests.resets('DydxBridge unit tests', env => { - const accountNumber = new BigNumber(1); + const defaultAccountNumber = new BigNumber(1); const marketId = new BigNumber(2); + const defaultAmount = new BigNumber(4); const notAuthorized = '0x0000000000000000000000000000000000000001'; let testContract: TestDydxBridgeContract; let authorized: string; @@ -30,147 +31,214 @@ blockchainTests.resets('DydxBridge unit tests', env => { }); describe('bridgeTransferFrom()', () => { - interface BridgeData { - action: number; - accountNumber: BigNumber; - marketId: BigNumber; - } - enum DydxBridgeActions { + enum BridgeActionType { Deposit, Withdraw, } - let defaultBridgeData: any; - let bridgeDataEncoder: AbiEncoder.DataType; + interface BrigeAction { + actionType: BridgeActionType; + accountId: BigNumber; + marketId: BigNumber; + conversionRateNumerator: BigNumber; + conversionRateDenominator: BigNumber; + } + interface BridgeData { + accountNumbers: BigNumber[]; + actions: BrigeAction[]; + } + const defaultDepositAction = { + actionType: BridgeActionType.Deposit as number, + accountId: constants.ZERO_AMOUNT, + marketId, + conversionRateNumerator: constants.ZERO_AMOUNT, + conversionRateDenominator: constants.ZERO_AMOUNT, + }; + const defaultWithdrawAction = { + actionType: BridgeActionType.Withdraw as number, + accountId: constants.ZERO_AMOUNT, + marketId, + conversionRateNumerator: constants.ZERO_AMOUNT, + conversionRateDenominator: constants.ZERO_AMOUNT, + }; + const bridgeDataEncoder = AbiEncoder.create([ + { + name: 'bridgeData', + type: 'tuple', + components: [ + { name: 'accountNumbers', type: 'uint256[]' }, + { + name: 'actions', + type: 'tuple[]', + components: [ + { name: 'actionType', type: 'uint8' }, + { name: 'accountId', type: 'uint256' }, + { name: 'marketId', type: 'uint256' }, + { name: 'conversionRateNumerator', type: 'uint256' }, + { name: 'conversionRateDenominator', type: 'uint256' }, + ], + }, + ], + }, + ]); const callBridgeTransferFrom = async ( from: string, to: string, + amount: BigNumber, bridgeData: BridgeData, sender: string, ): Promise => { const returnValue = await testContract - .bridgeTransferFrom( - constants.NULL_ADDRESS, - from, - to, - new BigNumber(1), - bridgeDataEncoder.encode(bridgeData), - ) + .bridgeTransferFrom(constants.NULL_ADDRESS, from, to, amount, bridgeDataEncoder.encode({ bridgeData })) .callAsync({ from: sender }); return returnValue; }; const callBridgeTransferFromAndVerifyEvents = async ( - actionType: number, - actionAddress: string, from: string, to: string, + amount: BigNumber, bridgeData: BridgeData, sender: string, ): Promise => { // Execute transaction. const txReceipt = await testContract - .bridgeTransferFrom( - constants.NULL_ADDRESS, - from, - to, - new BigNumber(1), - bridgeDataEncoder.encode(bridgeData), - ) + .bridgeTransferFrom(constants.NULL_ADDRESS, from, to, amount, bridgeDataEncoder.encode({ bridgeData })) .awaitTransactionSuccessAsync({ from: sender }); // Verify `OperateAccount` event. - verifyEventsFromLogs( - txReceipt.logs, - [ - { - owner: accountOwner, - number: accountNumber, - }, - ], - TestDydxBridgeEvents.OperateAccount, - ); + const expectedOperateAccountEvents = []; + for (const accountNumber of bridgeData.accountNumbers) { + expectedOperateAccountEvents.push({ + owner: accountOwner, + number: accountNumber, + }); + } + verifyEventsFromLogs(txReceipt.logs, expectedOperateAccountEvents, TestDydxBridgeEvents.OperateAccount); // Verify `OperateAction` event. - const accountId = new BigNumber(0); const positiveAmountSign = true; const weiDenomination = 0; const absoluteAmountRef = 1; - verifyEventsFromLogs( - txReceipt.logs, - [ + const expectedOperateActionEvents = []; + for (const action of bridgeData.actions) { + expectedOperateActionEvents.push({ + actionType: action.actionType as number, + accountId: action.accountId, + amountSign: positiveAmountSign, + amountDenomination: weiDenomination, + amountRef: absoluteAmountRef, + amountValue: action.conversionRateDenominator.gt(0) + ? amount.times(action.conversionRateNumerator).div(action.conversionRateDenominator) + : amount, + primaryMarketId: marketId, + secondaryMarketId: constants.ZERO_AMOUNT, + otherAddress: action.actionType === BridgeActionType.Deposit ? from : to, + otherAccountId: constants.ZERO_AMOUNT, + data: '0x', + }); + } + verifyEventsFromLogs(txReceipt.logs, expectedOperateActionEvents, TestDydxBridgeEvents.OperateAction); + }; + it('succeeds when calling `operate` with the `deposit` action and a single account', async () => { + const bridgeData = { + accountNumbers: [defaultAccountNumber], + actions: [defaultDepositAction], + }; + await callBridgeTransferFromAndVerifyEvents(accountOwner, receiver, defaultAmount, bridgeData, authorized); + }); + it('succeeds when calling `operate` with the `deposit` action and multiple accounts', async () => { + const bridgeData = { + accountNumbers: [defaultAccountNumber, defaultAccountNumber.plus(1)], + actions: [defaultDepositAction], + }; + await callBridgeTransferFromAndVerifyEvents(accountOwner, receiver, defaultAmount, bridgeData, authorized); + }); + it('succeeds when calling `operate` with the `withdraw` action and a single accuont', async () => { + const bridgeData = { + accountNumbers: [defaultAccountNumber], + actions: [defaultWithdrawAction], + }; + await callBridgeTransferFromAndVerifyEvents(accountOwner, receiver, defaultAmount, bridgeData, authorized); + }); + it('succeeds when calling `operate` with the `withdraw` action and multiple accounts', async () => { + const bridgeData = { + accountNumbers: [defaultAccountNumber, defaultAccountNumber.plus(1)], + actions: [defaultWithdrawAction], + }; + await callBridgeTransferFromAndVerifyEvents(accountOwner, receiver, defaultAmount, bridgeData, authorized); + }); + it('succeeds when calling `operate` with the `deposit` action and multiple accounts', async () => { + const bridgeData = { + accountNumbers: [defaultAccountNumber, defaultAccountNumber.plus(1)], + actions: [defaultWithdrawAction, defaultDepositAction], + }; + await callBridgeTransferFromAndVerifyEvents(accountOwner, receiver, defaultAmount, bridgeData, authorized); + }); + it('succeeds when calling `operate` with multiple actions under a single account', async () => { + const bridgeData = { + accountNumbers: [defaultAccountNumber], + actions: [defaultWithdrawAction, defaultDepositAction], + }; + await callBridgeTransferFromAndVerifyEvents(accountOwner, receiver, defaultAmount, bridgeData, authorized); + }); + it('succeeds when scaling the `amount` to deposit', async () => { + const conversionRateNumerator = new BigNumber(1); + const conversionRateDenominator = new BigNumber(2); + const bridgeData = { + accountNumbers: [defaultAccountNumber], + actions: [ + defaultWithdrawAction, { - actionType, - accountId, - amountSign: positiveAmountSign, - amountDenomination: weiDenomination, - amountRef: absoluteAmountRef, - amountValue: new BigNumber(1), - primaryMarketId: marketId, - secondaryMarketId: constants.ZERO_AMOUNT, - otherAddress: actionAddress, - otherAccountId: constants.ZERO_AMOUNT, - data: '0x', + ...defaultDepositAction, + conversionRateNumerator, + conversionRateDenominator, }, ], - TestDydxBridgeEvents.OperateAction, - ); - }; - before(async () => { - // Construct default bridge data - defaultBridgeData = { - action: DydxBridgeActions.Deposit as number, - accountNumber, - marketId, }; - - // Create encoder for bridge data - bridgeDataEncoder = AbiEncoder.create([ - { name: 'action', type: 'uint8' }, - { name: 'accountNumber', type: 'uint256' }, - { name: 'marketId', type: 'uint256' }, - ]); + await callBridgeTransferFromAndVerifyEvents(accountOwner, receiver, defaultAmount, bridgeData, authorized); }); - it('succeeds when calling `operate` with the `deposit` action', async () => { - const depositAction = 0; + it('succeeds when scaling the `amount` to withdraw', async () => { + const conversionRateNumerator = new BigNumber(1); + const conversionRateDenominator = new BigNumber(2); const bridgeData = { - ...defaultBridgeData, - action: depositAction, + accountNumbers: [defaultAccountNumber], + actions: [ + defaultDepositAction, + { + ...defaultWithdrawAction, + conversionRateNumerator, + conversionRateDenominator, + }, + ], }; - await callBridgeTransferFromAndVerifyEvents( - depositAction, - accountOwner, - receiver, - accountOwner, - bridgeData, - authorized, - ); - }); - it('succeeds when calling `operate` with the `withdraw` action', async () => { - const withdrawAction = 1; - const bridgeData = { - ...defaultBridgeData, - action: withdrawAction, - }; - await callBridgeTransferFromAndVerifyEvents( - withdrawAction, - receiver, - accountOwner, - receiver, - bridgeData, - authorized, - ); + await callBridgeTransferFromAndVerifyEvents(accountOwner, receiver, defaultAmount, bridgeData, authorized); }); it('reverts if not called by the ERC20 Bridge Proxy', async () => { + const bridgeData = { + accountNumbers: [defaultAccountNumber], + actions: [defaultDepositAction], + }; const callBridgeTransferFromPromise = callBridgeTransferFrom( accountOwner, receiver, - defaultBridgeData, + defaultAmount, + bridgeData, notAuthorized, ); const expectedError = RevertReason.DydxBridgeOnlyCallableByErc20BridgeProxy; return expect(callBridgeTransferFromPromise).to.revertWith(expectedError); }); it('should return magic bytes if call succeeds', async () => { - const returnValue = await callBridgeTransferFrom(accountOwner, receiver, defaultBridgeData, authorized); + const bridgeData = { + accountNumbers: [defaultAccountNumber], + actions: [defaultDepositAction], + }; + const returnValue = await callBridgeTransferFrom( + accountOwner, + receiver, + defaultAmount, + bridgeData, + authorized, + ); expect(returnValue).to.equal(AssetProxyId.ERC20Bridge); }); }); diff --git a/yarn.lock b/yarn.lock index 683bb659c7..144061f45b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -678,7 +678,7 @@ lodash "^4.17.11" valid-url "^1.0.9" -"@0x/base-contract@^5.5.0-beta.3", "@0x/base-contract@^5.5.0-beta.4": +"@0x/base-contract@^5.5.0-beta.3": version "5.5.0-beta.4" resolved "https://registry.yarnpkg.com/@0x/base-contract/-/base-contract-5.5.0-beta.4.tgz#eb26473e033e1a305a9fa87ab9e26325c9face59" dependencies: @@ -694,79 +694,26 @@ js-sha3 "^0.7.0" uuid "^3.3.2" -"@0x/contract-addresses@3.3.0-beta.4": - version "3.3.0-beta.4" - resolved "https://registry.yarnpkg.com/@0x/contract-addresses/-/contract-addresses-3.3.0-beta.4.tgz#eec4492702b2e707bcace6ac274f9826761e08a4" - dependencies: - lodash "^4.17.11" - -"@0x/contract-addresses@^3.3.0-beta.4", "@0x/contract-addresses@^3.3.0-beta.5": +"@0x/contract-addresses@^3.3.0-beta.4": version "3.3.0-beta.5" resolved "https://registry.yarnpkg.com/@0x/contract-addresses/-/contract-addresses-3.3.0-beta.5.tgz#9d5f80a258f1d103b127159c237f9bcdad182e80" dependencies: lodash "^4.17.11" -"@0x/contract-artifacts@^2.3.0-beta.3": - version "2.3.0-beta.4" - resolved "https://registry.yarnpkg.com/@0x/contract-artifacts/-/contract-artifacts-2.3.0-beta.4.tgz#ca056885be387344aaccf5c69fe80aec248df37d" - -"@0x/contract-wrappers@12.2.0-beta.3": - version "12.2.0-beta.3" - resolved "https://registry.yarnpkg.com/@0x/contract-wrappers/-/contract-wrappers-12.2.0-beta.3.tgz#e85a7e42170e98244ab57a1089f8831cf10e3f2d" +"@0x/coordinator-server@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@0x/coordinator-server/-/coordinator-server-1.0.5.tgz#3fda0d5f2af45f0baa7663ad0a5e8465b4161081" + integrity sha512-tR9OHa5QPejezSfjO++CorNF72jTKROGxqjSJ+7/Yk3w/RJFItUcAEJKgSQLMJpjJPKG7vbLkl53lzd9xuN+yw== dependencies: - "@0x/abi-gen-wrappers" "^5.4.0-beta.3" - "@0x/base-contract" "^5.5.0-beta.3" - "@0x/contract-addresses" "^3.3.0-beta.4" - "@0x/contract-artifacts" "^2.3.0-beta.3" - "@0x/order-utils" "^8.5.0-beta.3" - ethers "~4.0.4" - http-status-codes "^1.3.2" - -"@0x/contract-wrappers@^12.2.0-beta.4": - version "12.2.0-beta.4" - resolved "https://registry.npmjs.org/@0x/contract-wrappers/-/contract-wrappers-12.2.0-beta.4.tgz#7a7301dd50c28887879df4d385e80a49e040748d" - integrity sha512-JVoYG3Rd430fZw9ogBSqeLOaJXkqp9N7g614X5/bzzuG/dSDdwXl48X02m66aGFWcNofx/iMsT4tpOZrJ2bDBg== - dependencies: - "@0x/assert" "^2.2.0-beta.3" - "@0x/base-contract" "^5.5.0-beta.4" - "@0x/contract-addresses" "^3.3.0-beta.5" - "@0x/json-schemas" "^4.1.0-beta.3" - "@0x/types" "^2.5.0-beta.3" - "@0x/utils" "^4.6.0-beta.3" - "@0x/web3-wrapper" "^6.1.0-beta.3" - ethereum-types "^2.2.0-beta.2" - ethers "~4.0.4" - -"@0x/contracts-dev-utils@^0.1.0-beta.3": - version "0.1.0-beta.4" - resolved "https://registry.yarnpkg.com/@0x/contracts-dev-utils/-/contracts-dev-utils-0.1.0-beta.4.tgz#87f51a7ed778b619beb8b32bf08ea6b3e4495d4e" - dependencies: - "@0x/base-contract" "^5.5.0-beta.4" - -"@0x/contracts-erc20@2.3.0-beta.3": - version "2.3.0-beta.3" - resolved "https://registry.yarnpkg.com/@0x/contracts-erc20/-/contracts-erc20-2.3.0-beta.3.tgz#744f911d340576a27253b5961d52b09bb8659a98" - dependencies: - "@0x/base-contract" "^5.5.0-beta.3" - "@0x/types" "^2.5.0-beta.2" - "@0x/typescript-typings" "^4.4.0-beta.2" - ethereum-types "^2.2.0-beta.2" - -"@0x/coordinator-server@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@0x/coordinator-server/-/coordinator-server-1.0.4.tgz#9729ce789fb772a5ae0a8dcdf5928de9e80ac1af" - dependencies: - "@0x/assert" "2.2.0-beta.2" - "@0x/contract-addresses" "3.3.0-beta.4" - "@0x/contract-wrappers" "12.2.0-beta.3" - "@0x/contracts-erc20" "2.3.0-beta.3" - "@0x/json-schemas" "4.1.0-beta.2" - "@0x/order-utils" "8.5.0-beta.3" - "@0x/subproviders" "5.1.0-beta.2" - "@0x/types" "2.5.0-beta.2" - "@0x/typescript-typings" "4.4.0-beta.2" - "@0x/utils" "4.6.0-beta.2" - "@0x/web3-wrapper" "6.1.0-beta.2" + "@0x/assert" "^3.0.1" + "@0x/contract-addresses" "^4.0.0" + "@0x/contract-wrappers" "^13.1.0" + "@0x/json-schemas" "^5.0.1" + "@0x/order-utils" "^10.0.0" + "@0x/subproviders" "^6.0.1" + "@0x/types" "^3.1.0" + "@0x/typescript-typings" "^5.0.0" + "@0x/utils" "^5.1.0" "@babel/polyfill" "^7.0.0" body-parser "^1.18.3" cors "^2.8.5" @@ -781,15 +728,6 @@ typeorm "0.2.7" websocket "^1.0.25" -"@0x/json-schemas@4.1.0-beta.2": - version "4.1.0-beta.2" - resolved "https://registry.yarnpkg.com/@0x/json-schemas/-/json-schemas-4.1.0-beta.2.tgz#79d05d0c91525e2356f783dae5e572dd3624969f" - dependencies: - "@0x/typescript-typings" "^4.4.0-beta.2" - "@types/node" "*" - jsonschema "^1.2.0" - lodash.values "^4.3.0" - "@0x/json-schemas@^4.1.0-beta.2", "@0x/json-schemas@^4.1.0-beta.3": version "4.1.0-beta.3" resolved "https://registry.npmjs.org/@0x/json-schemas/-/json-schemas-4.1.0-beta.3.tgz#af70a35691108ea162140640bae93a7fc84ca6ee" @@ -813,68 +751,6 @@ uuid "^3.3.2" websocket "^1.0.29" -"@0x/order-utils@8.5.0-beta.3": - version "8.5.0-beta.3" - resolved "https://registry.yarnpkg.com/@0x/order-utils/-/order-utils-8.5.0-beta.3.tgz#67bc733cf64cb7cc5653a913e986c5f211b1b7d2" - dependencies: - "@0x/abi-gen-wrappers" "^5.4.0-beta.3" - "@0x/assert" "^2.2.0-beta.2" - "@0x/contract-addresses" "^3.3.0-beta.4" - "@0x/contract-artifacts" "^2.3.0-beta.3" - "@0x/contracts-dev-utils" "^0.1.0-beta.3" - "@0x/json-schemas" "^4.1.0-beta.2" - "@0x/types" "^2.5.0-beta.2" - "@0x/typescript-typings" "^4.4.0-beta.2" - "@0x/utils" "^4.6.0-beta.2" - "@0x/web3-wrapper" "^6.1.0-beta.2" - "@types/node" "*" - bn.js "^4.11.8" - ethereum-types "^2.2.0-beta.2" - ethereumjs-abi "0.6.5" - ethereumjs-util "^5.1.1" - ethers "~4.0.4" - lodash "^4.17.11" - -"@0x/order-utils@^8.5.0-beta.3": - version "8.5.0-beta.4" - resolved "https://registry.yarnpkg.com/@0x/order-utils/-/order-utils-8.5.0-beta.4.tgz#900387631008cc9dc9ece125d28450d2beaea462" - dependencies: - "@0x/assert" "^2.2.0-beta.3" - "@0x/contract-wrappers" "^12.2.0-beta.4" - "@0x/json-schemas" "^4.1.0-beta.3" - "@0x/utils" "^4.6.0-beta.3" - "@0x/web3-wrapper" "^6.1.0-beta.3" - ethereumjs-util "^5.1.1" - ethers "~4.0.4" - lodash "^4.17.11" - -"@0x/subproviders@5.1.0-beta.2": - version "5.1.0-beta.2" - resolved "https://registry.yarnpkg.com/@0x/subproviders/-/subproviders-5.1.0-beta.2.tgz#020369711330755448397b3b8cecf2868ae7c54c" - dependencies: - "@0x/assert" "^2.2.0-beta.2" - "@0x/types" "^2.5.0-beta.2" - "@0x/typescript-typings" "^4.4.0-beta.2" - "@0x/utils" "^4.6.0-beta.2" - "@0x/web3-wrapper" "^6.1.0-beta.2" - "@ledgerhq/hw-app-eth" "^4.3.0" - "@ledgerhq/hw-transport-u2f" "4.24.0" - "@types/hdkey" "^0.7.0" - "@types/web3-provider-engine" "^14.0.0" - bip39 "^2.5.0" - bn.js "^4.11.8" - ethereum-types "^2.2.0-beta.2" - ethereumjs-tx "^1.3.5" - ethereumjs-util "^5.1.1" - ganache-core "^2.6.0" - hdkey "^0.7.1" - json-rpc-error "2.0.0" - lodash "^4.17.11" - semaphore-async-await "^1.5.1" - web3-provider-engine "14.0.6" - optionalDependencies: - "@ledgerhq/hw-transport-node-hid" "^4.3.0" - "@0x/ts-doc-gen@^0.0.22": version "0.0.22" resolved "https://registry.yarnpkg.com/@0x/ts-doc-gen/-/ts-doc-gen-0.0.22.tgz#c9c215899695dcd4320a1711291be40050ddbc0e" @@ -934,24 +810,6 @@ ethereum-types "^2.1.6" popper.js "1.14.3" -"@0x/utils@4.6.0-beta.2": - version "4.6.0-beta.2" - resolved "https://registry.yarnpkg.com/@0x/utils/-/utils-4.6.0-beta.2.tgz#ffa70f05736a74ac8d7ca5debe01bff7e6d8f073" - dependencies: - "@0x/types" "^2.5.0-beta.2" - "@0x/typescript-typings" "^4.4.0-beta.2" - "@types/node" "*" - abortcontroller-polyfill "^1.1.9" - bignumber.js "~9.0.0" - chalk "^2.3.0" - detect-node "2.0.3" - ethereum-types "^2.2.0-beta.2" - ethereumjs-util "^5.1.1" - ethers "~4.0.4" - isomorphic-fetch "2.2.1" - js-sha3 "^0.7.0" - lodash "^4.17.11" - "@0x/utils@^4.3.3": version "4.5.2" resolved "https://registry.npmjs.org/@0x/utils/-/utils-4.5.2.tgz#6cc89f2d0dda341e0fb4e76049a35abfb67a4ac5" @@ -1005,19 +863,6 @@ websocket "^1.0.28" xhr2-cookies "1.1.0" -"@0x/web3-wrapper@6.1.0-beta.2": - version "6.1.0-beta.2" - resolved "https://registry.yarnpkg.com/@0x/web3-wrapper/-/web3-wrapper-6.1.0-beta.2.tgz#24aae8a0063057ebb6d3a7893a01d0abac8cd19c" - dependencies: - "@0x/assert" "^2.2.0-beta.2" - "@0x/json-schemas" "^4.1.0-beta.2" - "@0x/typescript-typings" "^4.4.0-beta.2" - "@0x/utils" "^4.6.0-beta.2" - ethereum-types "^2.2.0-beta.2" - ethereumjs-util "^5.1.1" - ethers "~4.0.4" - lodash "^4.17.11" - "@0x/web3-wrapper@^6.1.0-beta.2", "@0x/web3-wrapper@^6.1.0-beta.3": version "6.1.0-beta.3" resolved "https://registry.npmjs.org/@0x/web3-wrapper/-/web3-wrapper-6.1.0-beta.3.tgz#82161147e9283391e0c7cd6027c971749c5a2f77"