Updating bridge to work w/o MultiAssetProxy
This commit is contained in:
@@ -21,6 +21,7 @@ pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "@0x/contracts-utils/contracts/src/Authorizable.sol";
|
||||
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
|
||||
import "../interfaces/IERC20Bridge.sol";
|
||||
import "../interfaces/IDydxBridge.sol";
|
||||
import "../interfaces/IDydx.sol";
|
||||
@@ -33,15 +34,15 @@ contract DydxBridge is
|
||||
Authorizable
|
||||
{
|
||||
|
||||
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 dydx account that is being operated on.
|
||||
/// 2. This function may only be called in the context of the 0x Exchange executing an order
|
||||
/// (ERC20Bridge is authorized).
|
||||
/// 3. The order must be signed by the owner or an operator of the dydx account.
|
||||
/// This signature validated by the 0x Exchange.
|
||||
/// 4. The `from` address must be the maker (and hence is the owner or operator of the dydx account).
|
||||
/// This is asserted during execution of this function.
|
||||
/// 3. The `from` address must be the maker and owner of the dydx account.
|
||||
/// This signature is validated by the 0x Exchange.
|
||||
/// @param from The sender of the tokens.
|
||||
/// @param to The recipient of the tokens.
|
||||
/// @param amount Minimum amount of `toTokenAddress` tokens to buy.
|
||||
@@ -58,48 +59,62 @@ contract DydxBridge is
|
||||
onlyAuthorized
|
||||
returns (bytes4 success)
|
||||
{
|
||||
// Ensure that only the `ERC20BridgeProxy` can call this function.
|
||||
require(
|
||||
msg.sender == _getERC20BridgeProxyAddress(),
|
||||
"DydxBridge/ONLY_CALLABLE_BY_ERC20_BRIDGE_PROXY"
|
||||
);
|
||||
|
||||
// Decode bridge data.
|
||||
(BridgeData memory bridgeData) = abi.decode(encodedBridgeData, (BridgeData));
|
||||
|
||||
// Cache dydx contract.
|
||||
IDydx dydx = IDydx(_getDydxAddress());
|
||||
|
||||
// Assert that `from` is the owner or an operator of the dydx account.
|
||||
require(
|
||||
from == bridgeData.accountOwner || dydx.getIsLocalOperator(bridgeData.accountOwner, from),
|
||||
"INVALID_DYDX_OWNER_OR_OPERATOR"
|
||||
);
|
||||
|
||||
// Construct dydx account info.
|
||||
IDydx.AccountInfo[] memory accounts = new IDydx.AccountInfo[](1);
|
||||
accounts[0] = IDydx.AccountInfo({
|
||||
owner: bridgeData.accountOwner,
|
||||
IDydx.AccountInfo[] memory dydxAccounts = new IDydx.AccountInfo[](1);
|
||||
dydxAccounts[0] = IDydx.AccountInfo({
|
||||
owner: from,
|
||||
number: bridgeData.accountNumber
|
||||
});
|
||||
|
||||
// Create dydx action.
|
||||
IDydx.ActionArgs[] memory actions = new IDydx.ActionArgs[](1);
|
||||
if (bridgeData.action == BridgeAction.Deposit) {
|
||||
actions[0] = _createDepositAction(
|
||||
from,
|
||||
amount,
|
||||
bridgeData
|
||||
);
|
||||
} else if (bridgeData.action == BridgeAction.Withdraw) {
|
||||
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("UNRECOGNIZED_ACTION");
|
||||
IDydx.ActionArgs[] memory dydxActions = new IDydx.ActionArgs[](bridgeData.actions.length);
|
||||
for (uint256 i = 0; i < dydxActions.length; ++i) {
|
||||
BridgeAction bridgeAction = bridgeData.actions[i];
|
||||
if (bridgeAction == BridgeAction.Deposit) {
|
||||
// Compute the amount to deposit. The `amount` parameter is the amount to be withdrawn.
|
||||
// It is computed by the Exchange as:
|
||||
// amount = floor[(takerFillAmount * makerAssetAmount) / takerAssetAmount]
|
||||
// The amount to deposit is equal to to `takerFillAmount`, which we compute below as:
|
||||
// takerFillAmount ~= floor[(amount * takerAssetAmount) / makerAssetAmount]
|
||||
// = floor[(amount * conversionRateNumerator) / conversionRateDenominator]
|
||||
// Note that we can only approximate the original value of `takerFillAmount`. If we were to use
|
||||
// `ceil` then we would risk overestimating the value.
|
||||
uint256 amountToDeposit = amount
|
||||
.mul(bridgeData.conversionRateNumerator)
|
||||
.div(bridgeData.conversionRateDenominator);
|
||||
dydxActions[i] = _createDepositAction(
|
||||
from,
|
||||
amount,
|
||||
bridgeData
|
||||
);
|
||||
} else if (bridgeAction == BridgeAction.Withdraw) {
|
||||
dydxActions[i] = _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");
|
||||
}
|
||||
}
|
||||
|
||||
// Run operation. This will revert on failure.
|
||||
dydx.operate(accounts, actions);
|
||||
dydx.operate(dydxAccounts, dydxActions);
|
||||
return BRIDGE_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -117,7 +132,7 @@ contract DydxBridge is
|
||||
returns (IDydx.ActionArgs memory)
|
||||
{
|
||||
// Create dydx amount.
|
||||
IDydx.AssetAmount memory amountToDeposit = IDydx.AssetAmount({
|
||||
IDydx.AssetAmount memory dydxAmount = IDydx.AssetAmount({
|
||||
sign: true, // true if positive.
|
||||
denomination: IDydx.AssetDenomination.Wei, // Wei => actual token amount held in account.
|
||||
ref: IDydx.AssetReference.Target, // Target => an absolute amount.
|
||||
@@ -127,7 +142,7 @@ contract DydxBridge is
|
||||
// Create dydx deposit action.
|
||||
IDydx.ActionArgs memory depositAction = IDydx.ActionArgs({
|
||||
actionType: IDydx.ActionType.Deposit, // deposit tokens.
|
||||
amount: amountToDeposit, // amount to deposit.
|
||||
amount: dydxAmount, // amount to deposit.
|
||||
accountId: 0, // index in the `accounts` when calling `operate`.
|
||||
primaryMarketId: bridgeData.marketId, // indicates which token to deposit.
|
||||
otherAddress: depositFrom, // deposit from this address.
|
||||
|
||||
@@ -27,9 +27,10 @@ interface IDydxBridge {
|
||||
}
|
||||
|
||||
struct BridgeData {
|
||||
BridgeAction action; // Action to run on dydx account.
|
||||
address accountOwner; // The owner of the dydx account.
|
||||
uint256 accountNumber; // Account number used to identify the owner's specific account.
|
||||
uint256 marketId; // Market to operate on.
|
||||
BridgeAction[] actions; // 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 conversionRateNumerator; //
|
||||
uint256 conversionRateDenominator; //
|
||||
}
|
||||
}
|
||||
@@ -43,8 +43,12 @@
|
||||
"abis": "./test/generated-artifacts/@(ChaiBridge|DyDxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IChai|IDyDx|IERC20Bridge|IEth2Dai|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestChaiBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
|
||||
=======
|
||||
"publicInterfaceContracts": "ERC1155Proxy,ERC20Proxy,ERC721Proxy,MultiAssetProxy,StaticCallProxy,ERC20BridgeProxy,Eth2DaiBridge,IAssetData,IAssetProxy,UniswapBridge,KyberBridge,TestStaticCallTarget",
|
||||
<<<<<<< HEAD
|
||||
"abis": "./test/generated-artifacts/@(DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IDydx|IERC20Bridge|IEth2Dai|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
|
||||
>>>>>>> ee82a0f67... Consistent capitalization for "dydx"`
|
||||
=======
|
||||
"abis": "./test/generated-artifacts/@(DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
|
||||
>>>>>>> 5e2de489d... Updating bridge to work w/o MAP
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
|
||||
@@ -25,7 +25,11 @@ import * as IChai from '../test/generated-artifacts/IChai.json';
|
||||
import * as IDyDx from '../test/generated-artifacts/IDyDx.json';
|
||||
=======
|
||||
import * as IDydx from '../test/generated-artifacts/IDydx.json';
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> ee82a0f67... Consistent capitalization for "dydx"`
|
||||
=======
|
||||
import * as IDydxBridge from '../test/generated-artifacts/IDydxBridge.json';
|
||||
>>>>>>> 5e2de489d... Updating bridge to work w/o MAP
|
||||
import * as IERC20Bridge from '../test/generated-artifacts/IERC20Bridge.json';
|
||||
import * as IEth2Dai from '../test/generated-artifacts/IEth2Dai.json';
|
||||
import * as IKyberNetworkProxy from '../test/generated-artifacts/IKyberNetworkProxy.json';
|
||||
@@ -72,7 +76,11 @@ export const artifacts = {
|
||||
IDyDx: IDyDx as ContractArtifact,
|
||||
=======
|
||||
IDydx: IDydx as ContractArtifact,
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> ee82a0f67... Consistent capitalization for "dydx"`
|
||||
=======
|
||||
IDydxBridge: IDydxBridge as ContractArtifact,
|
||||
>>>>>>> 5e2de489d... Updating bridge to work w/o MAP
|
||||
IERC20Bridge: IERC20Bridge as ContractArtifact,
|
||||
IEth2Dai: IEth2Dai as ContractArtifact,
|
||||
IKyberNetworkProxy: IKyberNetworkProxy as ContractArtifact,
|
||||
|
||||
@@ -23,7 +23,11 @@ export * from '../test/generated-wrappers/i_chai';
|
||||
export * from '../test/generated-wrappers/i_dy_dx';
|
||||
=======
|
||||
export * from '../test/generated-wrappers/i_dydx';
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> ee82a0f67... Consistent capitalization for "dydx"`
|
||||
=======
|
||||
export * from '../test/generated-wrappers/i_dydx_bridge';
|
||||
>>>>>>> 5e2de489d... Updating bridge to work w/o MAP
|
||||
export * from '../test/generated-wrappers/i_erc20_bridge';
|
||||
export * from '../test/generated-wrappers/i_eth2_dai';
|
||||
export * from '../test/generated-wrappers/i_kyber_network_proxy';
|
||||
|
||||
@@ -36,7 +36,11 @@
|
||||
"test/generated-artifacts/IDyDx.json",
|
||||
=======
|
||||
"test/generated-artifacts/IDydx.json",
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> ee82a0f67... Consistent capitalization for "dydx"`
|
||||
=======
|
||||
"test/generated-artifacts/IDydxBridge.json",
|
||||
>>>>>>> 5e2de489d... Updating bridge to work w/o MAP
|
||||
"test/generated-artifacts/IERC20Bridge.json",
|
||||
"test/generated-artifacts/IEth2Dai.json",
|
||||
"test/generated-artifacts/IKyberNetworkProxy.json",
|
||||
|
||||
Reference in New Issue
Block a user