Reverted to version of dydx bridge that only allows from to be the account owner
This commit is contained in:
@@ -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,37 +65,89 @@ 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(
|
||||
// Create dydx actions to run on the dydx accounts.
|
||||
IDydx.ActionArgs[] memory actions = _createActions(
|
||||
from,
|
||||
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
|
||||
// Run operation. This will revert on failure.
|
||||
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
|
||||
@@ -102,21 +155,18 @@ contract DydxBridge is
|
||||
// from `uint8` to `Action`.
|
||||
revert("DydxBridge/UNRECOGNIZED_BRIDGE_ACTION");
|
||||
}
|
||||
|
||||
// Run operation. This will revert on failure.
|
||||
dydx.operate(accounts, actions);
|
||||
return BRIDGE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/// @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,
|
||||
|
||||
@@ -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 BridgeData {
|
||||
BridgeAction action; // Action to run on dydx account.
|
||||
uint256 accountNumber; // Account number used to identify the owner's specific 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 {
|
||||
uint256[] accountNumbers; // Account number used to identify the owner's specific account.
|
||||
BridgeAction[] actions; // Actions to carry out on the owner's accounts.
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ export {
|
||||
ERC20ProxyContract,
|
||||
ERC721ProxyContract,
|
||||
Eth2DaiBridgeContract,
|
||||
DydxBridgeContract,
|
||||
IAssetDataContract,
|
||||
IAssetProxyContract,
|
||||
MultiAssetProxyContract,
|
||||
|
||||
@@ -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<string> => {
|
||||
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<void> => {
|
||||
// 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,
|
||||
[
|
||||
{
|
||||
const expectedOperateAccountEvents = [];
|
||||
for (const accountNumber of bridgeData.accountNumbers) {
|
||||
expectedOperateAccountEvents.push({
|
||||
owner: accountOwner,
|
||||
number: accountNumber,
|
||||
},
|
||||
],
|
||||
TestDydxBridgeEvents.OperateAccount,
|
||||
);
|
||||
});
|
||||
}
|
||||
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,
|
||||
[
|
||||
{
|
||||
actionType,
|
||||
accountId,
|
||||
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: new BigNumber(1),
|
||||
amountValue: action.conversionRateDenominator.gt(0)
|
||||
? amount.times(action.conversionRateNumerator).div(action.conversionRateDenominator)
|
||||
: amount,
|
||||
primaryMarketId: marketId,
|
||||
secondaryMarketId: constants.ZERO_AMOUNT,
|
||||
otherAddress: actionAddress,
|
||||
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,
|
||||
{
|
||||
...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);
|
||||
});
|
||||
});
|
||||
|
||||
185
yarn.lock
185
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"
|
||||
|
||||
Reference in New Issue
Block a user