Compare commits
97 Commits
@0x/contra
...
@0x/contra
Author | SHA1 | Date | |
---|---|---|---|
|
58ff2dc492 | ||
|
13c45a0e96 | ||
|
be7b1a1bd4 | ||
|
132a3c6705 | ||
|
5e73257557 | ||
|
e83346fbbb | ||
|
2dd47a2103 | ||
|
f31e530b6e | ||
|
eb50f3fa9c | ||
|
8417fe4fdb | ||
|
0f1c15a6ca | ||
|
9345c4fb7f | ||
|
5e0758917b | ||
|
cbb23a42e2 | ||
|
5a59c286d0 | ||
|
2e8c600d7a | ||
|
e851cb1cbc | ||
|
3da03da32a | ||
|
3ec8924e7f | ||
|
a04722b612 | ||
|
f9a7857a90 | ||
|
58f772c74e | ||
|
a425c7e260 | ||
|
809885afd0 | ||
|
bf9b4b993f | ||
|
d94a26f0f4 | ||
|
bd9c9cedca | ||
|
651e94bd94 | ||
|
162b6f1a74 | ||
|
865a253eb5 | ||
|
9b3781abf1 | ||
|
d89243a0d3 | ||
|
b4cefc64b4 | ||
|
2fd26587e5 | ||
|
282a351859 | ||
|
a84b848ea9 | ||
|
d329320fc2 | ||
|
bc096554b5 | ||
|
5902d878d8 | ||
|
4a133ca36f | ||
|
f7252f919a | ||
|
e05a03a842 | ||
|
dcce8276b8 | ||
|
fd47947e55 | ||
|
ae151df2eb | ||
|
79de188683 | ||
|
6e5c788e13 | ||
|
f53606007d | ||
|
a4ac418bc9 | ||
|
a8c09d0bdb | ||
|
871105a48a | ||
|
3b61129ade | ||
|
f471c79b59 | ||
|
dfd9443f74 | ||
|
a36ff9e365 | ||
|
12e65bbf26 | ||
|
ab9841e60b | ||
|
7a52f12e57 | ||
|
11fd4506ac | ||
|
0c9c68030e | ||
|
55d6eddbb2 | ||
|
8341e60edb | ||
|
6273a1ca73 | ||
|
1b83ebdf89 | ||
|
fef7f0506f | ||
|
f44eb4e383 | ||
|
05df485c4a | ||
|
44857c526b | ||
|
b8ad5d5d32 | ||
|
e3e0d00e21 | ||
|
a9b1ea9690 | ||
|
8e5dd0f8d9 | ||
|
3b0c8f6d92 | ||
|
21058c2227 | ||
|
f3b8ae0781 | ||
|
d590b004c1 | ||
|
02e21141c6 | ||
|
f839a3087d | ||
|
f458815541 | ||
|
7ba754d2a4 | ||
|
09706e4ae2 | ||
|
d18de4c541 | ||
|
001c7bfdbc | ||
|
d4e04dc712 | ||
|
8650cb5217 | ||
|
0eaaddeb95 | ||
|
1cf8663f20 | ||
|
5130259552 | ||
|
ba5e19a015 | ||
|
c0400fa986 | ||
|
51179d10ce | ||
|
78752f9178 | ||
|
762db417d7 | ||
|
85bdccbc06 | ||
|
9f8cb99340 | ||
|
87b90bb04b | ||
|
e961d88277 |
@@ -91,3 +91,4 @@ packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json
|
||||
packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json
|
||||
packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json
|
||||
packages/*/docs
|
||||
*.sol
|
||||
|
@@ -1,7 +1,42 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "3.2.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "3.2.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1581748629,
|
||||
"version": "3.2.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "3.2.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add more types and functions to `IDydx`",
|
||||
"pr": 2466
|
||||
},
|
||||
{
|
||||
"note": "Rename `DydxBrigeAction.accountId` to `DydxBridgeAction.accountIdx`",
|
||||
"pr": 2466
|
||||
},
|
||||
{
|
||||
"note": "Fix broken tests.",
|
||||
"pr": 2462
|
||||
@@ -13,6 +48,10 @@
|
||||
{
|
||||
"note": "Add asset data decoding functions",
|
||||
"pr": 2462
|
||||
},
|
||||
{
|
||||
"note": "Add `setOperators()` to `IDydx`",
|
||||
"pr": "TODO"
|
||||
}
|
||||
],
|
||||
"timestamp": 1581204851
|
||||
|
@@ -5,11 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.2.3 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.2 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.1 - _February 15, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.0 - _February 8, 2020_
|
||||
|
||||
* Add more types and functions to `IDydx` (#2466)
|
||||
* Rename `DydxBrigeAction.accountId` to `DydxBridgeAction.accountIdx` (#2466)
|
||||
* Fix broken tests. (#2462)
|
||||
* Remove dependency on `@0x/contracts-dev-utils` (#2462)
|
||||
* Add asset data decoding functions (#2462)
|
||||
* Add `setOperators()` to `IDydx` (#TODO)
|
||||
|
||||
## v3.1.3 - _February 6, 2020_
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
108
contracts/asset-proxy/contracts/src/bridges/CurveBridge.sol
Normal file
108
contracts/asset-proxy/contracts/src/bridges/CurveBridge.sol
Normal file
@@ -0,0 +1,108 @@
|
||||
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "../interfaces/IERC20Bridge.sol";
|
||||
import "../interfaces/ICurve.sol";
|
||||
|
||||
|
||||
// solhint-disable not-rely-on-time
|
||||
// solhint-disable space-after-comma
|
||||
contract CurveBridge is
|
||||
IERC20Bridge,
|
||||
IWallet,
|
||||
DeploymentConstants
|
||||
{
|
||||
/// @dev Callback for `ICurve`. Tries to buy `amount` of
|
||||
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
|
||||
/// (DAI, USDC) to the Curve contract, then transfers the bought
|
||||
/// tokens to `to`.
|
||||
/// @param toTokenAddress The token to give to `to` (i.e DAI, USDC, USDT).
|
||||
/// @param to The recipient of the bought tokens.
|
||||
/// @param amount Minimum amount of `toTokenAddress` tokens to buy.
|
||||
/// @param bridgeData The abi-encoeded "from" token address.
|
||||
/// @return success The magic bytes if successful.
|
||||
function bridgeTransferFrom(
|
||||
address toTokenAddress,
|
||||
address /* from */,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes calldata bridgeData
|
||||
)
|
||||
external
|
||||
returns (bytes4 success)
|
||||
{
|
||||
// Decode the bridge data to get the Curve metadata.
|
||||
(address curveAddress, int128 fromCoinIdx, int128 toCoinIdx, int128 version) = abi.decode(bridgeData, (address, int128, int128, int128));
|
||||
ICurve exchange = ICurve(curveAddress);
|
||||
|
||||
address fromTokenAddress = exchange.underlying_coins(fromCoinIdx);
|
||||
require(toTokenAddress != fromTokenAddress, "CurveBridge/INVALID_PAIR");
|
||||
// Grant an allowance to the exchange to spend `fromTokenAddress` token.
|
||||
LibERC20Token.approve(fromTokenAddress, address(exchange), uint256(-1));
|
||||
|
||||
// Try to sell all of this contract's `fromTokenAddress` token balance.
|
||||
if (version == 0) {
|
||||
exchange.exchange_underlying(
|
||||
fromCoinIdx,
|
||||
toCoinIdx,
|
||||
// dx
|
||||
IERC20Token(fromTokenAddress).balanceOf(address(this)),
|
||||
// min dy
|
||||
amount,
|
||||
// expires
|
||||
block.timestamp + 1
|
||||
);
|
||||
} else {
|
||||
exchange.exchange_underlying(
|
||||
fromCoinIdx,
|
||||
toCoinIdx,
|
||||
// dx
|
||||
IERC20Token(fromTokenAddress).balanceOf(address(this)),
|
||||
// min dy
|
||||
amount
|
||||
);
|
||||
}
|
||||
|
||||
uint256 toTokenBalance = IERC20Token(toTokenAddress).balanceOf(address(this));
|
||||
// Transfer the converted `toToken`s to `to`.
|
||||
LibERC20Token.transfer(toTokenAddress, to, toTokenBalance);
|
||||
return BRIDGE_SUCCESS;
|
||||
}
|
||||
|
||||
/// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker
|
||||
/// and sign for itself in orders. Always succeeds.
|
||||
/// @return magicValue Magic success bytes, always.
|
||||
function isValidSignature(
|
||||
bytes32,
|
||||
bytes calldata
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bytes4 magicValue)
|
||||
{
|
||||
return LEGACY_WALLET_MAGIC_VALUE;
|
||||
}
|
||||
}
|
@@ -191,12 +191,12 @@ contract DydxBridge is
|
||||
depositAction = IDydx.ActionArgs({
|
||||
actionType: IDydx.ActionType.Deposit, // deposit tokens.
|
||||
amount: dydxAmount, // amount to deposit.
|
||||
accountId: bridgeAction.accountId, // index in the `accounts` when calling `operate`.
|
||||
accountIdx: bridgeAction.accountIdx, // 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,
|
||||
otherAccountId: 0,
|
||||
otherAccountIdx: 0,
|
||||
data: hex''
|
||||
});
|
||||
}
|
||||
@@ -229,12 +229,12 @@ contract DydxBridge is
|
||||
withdrawAction = IDydx.ActionArgs({
|
||||
actionType: IDydx.ActionType.Withdraw, // withdraw tokens.
|
||||
amount: amountToWithdraw, // amount to withdraw.
|
||||
accountId: bridgeAction.accountId, // index in the `accounts` when calling `operate`.
|
||||
accountIdx: bridgeAction.accountIdx, // 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,
|
||||
otherAccountId: 0,
|
||||
otherAccountIdx: 0,
|
||||
data: hex''
|
||||
});
|
||||
}
|
||||
|
87
contracts/asset-proxy/contracts/src/interfaces/ICurve.sol
Normal file
87
contracts/asset-proxy/contracts/src/interfaces/ICurve.sol
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
|
||||
// solhint-disable func-name-mixedcase
|
||||
interface ICurve {
|
||||
|
||||
/// @dev Sell `sellAmount` of `fromToken` token and receive `toToken` token.
|
||||
/// This function exists on early versions of Curve (USDC/DAI)
|
||||
/// @param i The token index being sold.
|
||||
/// @param j The token index being bought.
|
||||
/// @param sellAmount The amount of token being bought.
|
||||
/// @param minBuyAmount The minimum buy amount of the token being bought.
|
||||
/// @param deadline The time in seconds when this operation should expire.
|
||||
function exchange_underlying(
|
||||
int128 i,
|
||||
int128 j,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount,
|
||||
uint256 deadline
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Sell `sellAmount` of `fromToken` token and receive `toToken` token.
|
||||
/// This function exists on later versions of Curve (USDC/DAI/USDT)
|
||||
/// @param i The token index being sold.
|
||||
/// @param j The token index being bought.
|
||||
/// @param sellAmount The amount of token being bought.
|
||||
/// @param minBuyAmount The minimum buy amount of the token being bought.
|
||||
function exchange_underlying(
|
||||
int128 i,
|
||||
int128 j,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Get the amount of `toToken` by selling `sellAmount` of `fromToken`
|
||||
/// @param i The token index being sold.
|
||||
/// @param j The token index being bought.
|
||||
/// @param sellAmount The amount of token being bought.
|
||||
function get_dy_underlying(
|
||||
int128 i,
|
||||
int128 j,
|
||||
uint256 sellAmount
|
||||
)
|
||||
external
|
||||
returns (uint256 dy);
|
||||
|
||||
/// @dev Get the amount of `fromToken` by buying `buyAmount` of `toToken`
|
||||
/// This function exists on later versions of Curve (USDC/DAI/USDT)
|
||||
/// @param i The token index being sold.
|
||||
/// @param j The token index being bought.
|
||||
/// @param buyAmount The amount of token being bought.
|
||||
function get_dx_underlying(
|
||||
int128 i,
|
||||
int128 j,
|
||||
uint256 buyAmount
|
||||
)
|
||||
external
|
||||
returns (uint256 dx);
|
||||
|
||||
/// @dev Get the underlying token address from the token index
|
||||
/// @param i The token index.
|
||||
function underlying_coins(
|
||||
int128 i
|
||||
)
|
||||
external
|
||||
returns (address tokenAddress);
|
||||
}
|
@@ -45,12 +45,12 @@ interface IDydx {
|
||||
/// parsed into before being processed.
|
||||
struct ActionArgs {
|
||||
ActionType actionType;
|
||||
uint256 accountId;
|
||||
uint256 accountIdx;
|
||||
AssetAmount amount;
|
||||
uint256 primaryMarketId;
|
||||
uint256 secondaryMarketId;
|
||||
address otherAddress;
|
||||
uint256 otherAccountId;
|
||||
uint256 otherAccountIdx;
|
||||
bytes data;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,36 @@ interface IDydx {
|
||||
uint256 value;
|
||||
}
|
||||
|
||||
struct D256 {
|
||||
uint256 value;
|
||||
}
|
||||
|
||||
struct Value {
|
||||
uint256 value;
|
||||
}
|
||||
|
||||
struct Price {
|
||||
uint256 value;
|
||||
}
|
||||
|
||||
struct OperatorArg {
|
||||
address operator;
|
||||
bool trusted;
|
||||
}
|
||||
|
||||
/// @dev The global risk parameters that govern the health and security of the system
|
||||
struct RiskParams {
|
||||
// Required ratio of over-collateralization
|
||||
D256 marginRatio;
|
||||
// Percentage penalty incurred by liquidated accounts
|
||||
D256 liquidationSpread;
|
||||
// Percentage of the borrower's interest fee that gets passed to the suppliers
|
||||
D256 earningsRate;
|
||||
// The minimum absolute borrow value of an account
|
||||
// There must be sufficient incentivize to liquidate undercollateralized accounts
|
||||
Value minBorrowedValue;
|
||||
}
|
||||
|
||||
/// @dev The main entry-point to Solo that allows users and contracts to manage accounts.
|
||||
/// Take one or more actions on one or more accounts. The msg.sender must be the owner or
|
||||
/// operator of all accounts except for those being liquidated, vaporized, or traded with.
|
||||
@@ -86,4 +116,77 @@ interface IDydx {
|
||||
ActionArgs[] calldata actions
|
||||
)
|
||||
external;
|
||||
|
||||
// @dev Approves/disapproves any number of operators. An operator is an external address that has the
|
||||
// same permissions to manipulate an account as the owner of the account. Operators are simply
|
||||
// addresses and therefore may either be externally-owned Ethereum accounts OR smart contracts.
|
||||
// Operators are also able to act as AutoTrader contracts on behalf of the account owner if the
|
||||
// operator is a smart contract and implements the IAutoTrader interface.
|
||||
// @param args A list of OperatorArgs which have an address and a boolean. The boolean value
|
||||
// denotes whether to approve (true) or revoke approval (false) for that address.
|
||||
function setOperators(OperatorArg[] calldata args) external;
|
||||
|
||||
/// @dev Return true if a particular address is approved as an operator for an owner's accounts.
|
||||
/// Approved operators can act on the accounts of the owner as if it were the operator's own.
|
||||
/// @param owner The owner of the accounts
|
||||
/// @param operator The possible operator
|
||||
/// @return isLocalOperator True if operator is approved for owner's accounts
|
||||
function getIsLocalOperator(
|
||||
address owner,
|
||||
address operator
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bool isLocalOperator);
|
||||
|
||||
/// @dev Get the ERC20 token address for a market.
|
||||
/// @param marketId The market to query
|
||||
/// @return tokenAddress The token address
|
||||
function getMarketTokenAddress(
|
||||
uint256 marketId
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (address tokenAddress);
|
||||
|
||||
/// @dev Get all risk parameters in a single struct.
|
||||
/// @return riskParams All global risk parameters
|
||||
function getRiskParams()
|
||||
external
|
||||
view
|
||||
returns (RiskParams memory riskParams);
|
||||
|
||||
/// @dev Get the price of the token for a market.
|
||||
/// @param marketId The market to query
|
||||
/// @return price The price of each atomic unit of the token
|
||||
function getMarketPrice(
|
||||
uint256 marketId
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (Price memory price);
|
||||
|
||||
/// @dev Get the margin premium for a market. A margin premium makes it so that any positions that
|
||||
/// include the market require a higher collateralization to avoid being liquidated.
|
||||
/// @param marketId The market to query
|
||||
/// @return premium The market's margin premium
|
||||
function getMarketMarginPremium(uint256 marketId)
|
||||
external
|
||||
view
|
||||
returns (D256 memory premium);
|
||||
|
||||
/// @dev Get the total supplied and total borrowed values of an account adjusted by the marginPremium
|
||||
/// of each market. Supplied values are divided by (1 + marginPremium) for each market and
|
||||
/// borrowed values are multiplied by (1 + marginPremium) for each market. Comparing these
|
||||
/// adjusted values gives the margin-ratio of the account which will be compared to the global
|
||||
/// margin-ratio when determining if the account can be liquidated.
|
||||
/// @param account The account to query
|
||||
/// @return supplyValue The supplied value of the account (adjusted for marginPremium)
|
||||
/// @return borrowValue The borrowed value of the account (adjusted for marginPremium)
|
||||
function getAdjustedAccountValues(
|
||||
AccountInfo calldata account
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (Value memory supplyValue, Value memory borrowValue);
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ interface IDydxBridge {
|
||||
|
||||
struct BridgeAction {
|
||||
BridgeActionType actionType; // Action to run on dydx account.
|
||||
uint256 accountId; // Index in `BridgeData.accountNumbers` for this action.
|
||||
uint256 accountIdx; // 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).
|
||||
@@ -39,4 +39,4 @@ interface IDydxBridge {
|
||||
uint256[] accountNumbers; // Account number used to identify the owner's specific account.
|
||||
BridgeAction[] actions; // Actions to carry out on the owner's accounts.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||
import "../src/bridges/DydxBridge.sol";
|
||||
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
contract TestDydxBridgeToken {
|
||||
|
||||
uint256 private constant INIT_HOLDER_BALANCE = 10 * 10**18; // 10 tokens
|
||||
@@ -79,7 +80,7 @@ contract TestDydxBridge is
|
||||
|
||||
event OperateAction(
|
||||
ActionType actionType,
|
||||
uint256 accountId,
|
||||
uint256 accountIdx,
|
||||
bool amountSign,
|
||||
AssetDenomination amountDenomination,
|
||||
AssetReference amountRef,
|
||||
@@ -120,7 +121,7 @@ contract TestDydxBridge is
|
||||
for (uint i = 0; i < actions.length; ++i) {
|
||||
emit OperateAction(
|
||||
actions[i].actionType,
|
||||
actions[i].accountId,
|
||||
actions[i].accountIdx,
|
||||
actions[i].amount.sign,
|
||||
actions[i].amount.denomination,
|
||||
actions[i].amount.ref,
|
||||
@@ -128,7 +129,7 @@ contract TestDydxBridge is
|
||||
actions[i].primaryMarketId,
|
||||
actions[i].secondaryMarketId,
|
||||
actions[i].otherAddress,
|
||||
actions[i].otherAccountId,
|
||||
actions[i].otherAccountIdx,
|
||||
actions[i].data
|
||||
);
|
||||
|
||||
@@ -171,6 +172,60 @@ contract TestDydxBridge is
|
||||
return _testTokenAddress;
|
||||
}
|
||||
|
||||
/// @dev Unused.
|
||||
function setOperators(OperatorArg[] calldata args) external {}
|
||||
|
||||
/// @dev Unused.
|
||||
function getIsLocalOperator(
|
||||
address owner,
|
||||
address operator
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bool isLocalOperator)
|
||||
{}
|
||||
|
||||
/// @dev Unused.
|
||||
function getMarketTokenAddress(
|
||||
uint256 marketId
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (address tokenAddress)
|
||||
{}
|
||||
|
||||
/// @dev Unused.
|
||||
function getRiskParams()
|
||||
external
|
||||
view
|
||||
returns (RiskParams memory riskParams)
|
||||
{}
|
||||
|
||||
/// @dev Unsused.
|
||||
function getMarketPrice(
|
||||
uint256 marketId
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (Price memory price)
|
||||
{}
|
||||
|
||||
/// @dev Unsused
|
||||
function getMarketMarginPremium(uint256 marketId)
|
||||
external
|
||||
view
|
||||
returns (IDydx.D256 memory premium)
|
||||
{}
|
||||
|
||||
/// @dev Unused.
|
||||
function getAdjustedAccountValues(
|
||||
AccountInfo calldata account
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (Value memory supplyValue, Value memory borrowValue)
|
||||
{}
|
||||
|
||||
/// @dev overrides `_getDydxAddress()` from `DeploymentConstants` to return this address.
|
||||
function _getDydxAddress()
|
||||
internal
|
||||
@@ -188,4 +243,4 @@ contract TestDydxBridge is
|
||||
{
|
||||
return msg.sender == ALWAYS_REVERT_ADDRESS ? address(0) : msg.sender;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-asset-proxy",
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -38,7 +38,7 @@
|
||||
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||
},
|
||||
"config": {
|
||||
"abis": "./test/generated-artifacts/@(ChaiBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IChai|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestChaiBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
|
||||
"abis": "./test/generated-artifacts/@(ChaiBridge|CurveBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestChaiBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
@@ -51,12 +51,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@types/lodash": "4.14.104",
|
||||
@@ -78,16 +78,16 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0",
|
||||
"@0x/contracts-erc1155": "^2.1.0",
|
||||
"@0x/contracts-erc20": "^3.1.0",
|
||||
"@0x/contracts-erc721": "^3.1.0",
|
||||
"@0x/contracts-exchange-libs": "^4.3.0",
|
||||
"@0x/order-utils": "^10.2.0",
|
||||
"@0x/base-contract": "^6.2.1",
|
||||
"@0x/contracts-erc1155": "^2.1.3",
|
||||
"@0x/contracts-erc20": "^3.1.3",
|
||||
"@0x/contracts-erc721": "^3.1.3",
|
||||
"@0x/contracts-exchange-libs": "^4.3.3",
|
||||
"@0x/order-utils": "^10.2.2",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"ethereum-types": "^3.1.0",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
|
@@ -6,6 +6,7 @@
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as ChaiBridge from '../generated-artifacts/ChaiBridge.json';
|
||||
import * as CurveBridge from '../generated-artifacts/CurveBridge.json';
|
||||
import * as DydxBridge from '../generated-artifacts/DydxBridge.json';
|
||||
import * as ERC1155Proxy from '../generated-artifacts/ERC1155Proxy.json';
|
||||
import * as ERC20BridgeProxy from '../generated-artifacts/ERC20BridgeProxy.json';
|
||||
@@ -17,6 +18,7 @@ import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json';
|
||||
import * as IAssetProxyDispatcher from '../generated-artifacts/IAssetProxyDispatcher.json';
|
||||
import * as IAuthorizable from '../generated-artifacts/IAuthorizable.json';
|
||||
import * as IChai from '../generated-artifacts/IChai.json';
|
||||
import * as ICurve from '../generated-artifacts/ICurve.json';
|
||||
import * as IDydx from '../generated-artifacts/IDydx.json';
|
||||
import * as IDydxBridge from '../generated-artifacts/IDydxBridge.json';
|
||||
import * as IERC20Bridge from '../generated-artifacts/IERC20Bridge.json';
|
||||
@@ -49,6 +51,7 @@ export const artifacts = {
|
||||
MultiAssetProxy: MultiAssetProxy as ContractArtifact,
|
||||
StaticCallProxy: StaticCallProxy as ContractArtifact,
|
||||
ChaiBridge: ChaiBridge as ContractArtifact,
|
||||
CurveBridge: CurveBridge as ContractArtifact,
|
||||
DydxBridge: DydxBridge as ContractArtifact,
|
||||
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
||||
KyberBridge: KyberBridge as ContractArtifact,
|
||||
@@ -58,6 +61,7 @@ export const artifacts = {
|
||||
IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact,
|
||||
IAuthorizable: IAuthorizable as ContractArtifact,
|
||||
IChai: IChai as ContractArtifact,
|
||||
ICurve: ICurve as ContractArtifact,
|
||||
IDydx: IDydx as ContractArtifact,
|
||||
IDydxBridge: IDydxBridge as ContractArtifact,
|
||||
IERC20Bridge: IERC20Bridge as ContractArtifact,
|
||||
|
@@ -7,7 +7,7 @@ export enum DydxBridgeActionType {
|
||||
|
||||
export interface DydxBridgeAction {
|
||||
actionType: DydxBridgeActionType;
|
||||
accountId: BigNumber;
|
||||
accountIdx: BigNumber;
|
||||
marketId: BigNumber;
|
||||
conversionRateNumerator: BigNumber;
|
||||
conversionRateDenominator: BigNumber;
|
||||
@@ -29,7 +29,7 @@ export const dydxBridgeDataEncoder = AbiEncoder.create([
|
||||
type: 'tuple[]',
|
||||
components: [
|
||||
{ name: 'actionType', type: 'uint8' },
|
||||
{ name: 'accountId', type: 'uint256' },
|
||||
{ name: 'accountIdx', type: 'uint256' },
|
||||
{ name: 'marketId', type: 'uint256' },
|
||||
{ name: 'conversionRateNumerator', type: 'uint256' },
|
||||
{ name: 'conversionRateDenominator', type: 'uint256' },
|
||||
|
@@ -1,21 +1,22 @@
|
||||
export { artifacts } from './artifacts';
|
||||
export {
|
||||
ChaiBridgeContract,
|
||||
ERC1155ProxyContract,
|
||||
ERC20BridgeProxyContract,
|
||||
ERC20ProxyContract,
|
||||
ERC721ProxyContract,
|
||||
Eth2DaiBridgeContract,
|
||||
DydxBridgeContract,
|
||||
TestDydxBridgeContract,
|
||||
IAssetDataContract,
|
||||
IAssetProxyContract,
|
||||
IChaiContract,
|
||||
IDydxContract,
|
||||
KyberBridgeContract,
|
||||
MultiAssetProxyContract,
|
||||
StaticCallProxyContract,
|
||||
TestDydxBridgeContract,
|
||||
TestStaticCallTargetContract,
|
||||
UniswapBridgeContract,
|
||||
KyberBridgeContract,
|
||||
ChaiBridgeContract,
|
||||
IChaiContract,
|
||||
} from './wrappers';
|
||||
|
||||
export { ERC20Wrapper } from './erc20_wrapper';
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
export * from '../generated-wrappers/chai_bridge';
|
||||
export * from '../generated-wrappers/curve_bridge';
|
||||
export * from '../generated-wrappers/dydx_bridge';
|
||||
export * from '../generated-wrappers/erc1155_proxy';
|
||||
export * from '../generated-wrappers/erc20_bridge_proxy';
|
||||
@@ -15,6 +16,7 @@ export * from '../generated-wrappers/i_asset_proxy';
|
||||
export * from '../generated-wrappers/i_asset_proxy_dispatcher';
|
||||
export * from '../generated-wrappers/i_authorizable';
|
||||
export * from '../generated-wrappers/i_chai';
|
||||
export * from '../generated-wrappers/i_curve';
|
||||
export * from '../generated-wrappers/i_dydx';
|
||||
export * from '../generated-wrappers/i_dydx_bridge';
|
||||
export * from '../generated-wrappers/i_erc20_bridge';
|
||||
|
@@ -6,6 +6,7 @@
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.json';
|
||||
import * as CurveBridge from '../test/generated-artifacts/CurveBridge.json';
|
||||
import * as DydxBridge from '../test/generated-artifacts/DydxBridge.json';
|
||||
import * as ERC1155Proxy from '../test/generated-artifacts/ERC1155Proxy.json';
|
||||
import * as ERC20BridgeProxy from '../test/generated-artifacts/ERC20BridgeProxy.json';
|
||||
@@ -17,6 +18,7 @@ import * as IAssetProxy from '../test/generated-artifacts/IAssetProxy.json';
|
||||
import * as IAssetProxyDispatcher from '../test/generated-artifacts/IAssetProxyDispatcher.json';
|
||||
import * as IAuthorizable from '../test/generated-artifacts/IAuthorizable.json';
|
||||
import * as IChai from '../test/generated-artifacts/IChai.json';
|
||||
import * as ICurve from '../test/generated-artifacts/ICurve.json';
|
||||
import * as IDydx from '../test/generated-artifacts/IDydx.json';
|
||||
import * as IDydxBridge from '../test/generated-artifacts/IDydxBridge.json';
|
||||
import * as IERC20Bridge from '../test/generated-artifacts/IERC20Bridge.json';
|
||||
@@ -49,6 +51,7 @@ export const artifacts = {
|
||||
MultiAssetProxy: MultiAssetProxy as ContractArtifact,
|
||||
StaticCallProxy: StaticCallProxy as ContractArtifact,
|
||||
ChaiBridge: ChaiBridge as ContractArtifact,
|
||||
CurveBridge: CurveBridge as ContractArtifact,
|
||||
DydxBridge: DydxBridge as ContractArtifact,
|
||||
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
||||
KyberBridge: KyberBridge as ContractArtifact,
|
||||
@@ -58,6 +61,7 @@ export const artifacts = {
|
||||
IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact,
|
||||
IAuthorizable: IAuthorizable as ContractArtifact,
|
||||
IChai: IChai as ContractArtifact,
|
||||
ICurve: ICurve as ContractArtifact,
|
||||
IDydx: IDydx as ContractArtifact,
|
||||
IDydxBridge: IDydxBridge as ContractArtifact,
|
||||
IERC20Bridge: IERC20Bridge as ContractArtifact,
|
||||
|
@@ -17,14 +17,14 @@ blockchainTests.resets('DydxBridge unit tests', env => {
|
||||
const notAuthorized = '0x0000000000000000000000000000000000000001';
|
||||
const defaultDepositAction = {
|
||||
actionType: DydxBridgeActionType.Deposit,
|
||||
accountId: constants.ZERO_AMOUNT,
|
||||
accountIdx: constants.ZERO_AMOUNT,
|
||||
marketId,
|
||||
conversionRateNumerator: constants.ZERO_AMOUNT,
|
||||
conversionRateDenominator: constants.ZERO_AMOUNT,
|
||||
};
|
||||
const defaultWithdrawAction = {
|
||||
actionType: DydxBridgeActionType.Withdraw,
|
||||
accountId: constants.ZERO_AMOUNT,
|
||||
accountIdx: constants.ZERO_AMOUNT,
|
||||
marketId,
|
||||
conversionRateNumerator: constants.ZERO_AMOUNT,
|
||||
conversionRateDenominator: constants.ZERO_AMOUNT,
|
||||
@@ -118,7 +118,7 @@ blockchainTests.resets('DydxBridge unit tests', env => {
|
||||
for (const action of bridgeData.actions) {
|
||||
expectedOperateActionEvents.push({
|
||||
actionType: action.actionType as number,
|
||||
accountId: action.accountId,
|
||||
accountIdx: action.accountIdx,
|
||||
amountSign: action.actionType === DydxBridgeActionType.Deposit ? true : false,
|
||||
amountDenomination: weiDenomination,
|
||||
amountRef: deltaAmountRef,
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
export * from '../test/generated-wrappers/chai_bridge';
|
||||
export * from '../test/generated-wrappers/curve_bridge';
|
||||
export * from '../test/generated-wrappers/dydx_bridge';
|
||||
export * from '../test/generated-wrappers/erc1155_proxy';
|
||||
export * from '../test/generated-wrappers/erc20_bridge_proxy';
|
||||
@@ -15,6 +16,7 @@ export * from '../test/generated-wrappers/i_asset_proxy';
|
||||
export * from '../test/generated-wrappers/i_asset_proxy_dispatcher';
|
||||
export * from '../test/generated-wrappers/i_authorizable';
|
||||
export * from '../test/generated-wrappers/i_chai';
|
||||
export * from '../test/generated-wrappers/i_curve';
|
||||
export * from '../test/generated-wrappers/i_dydx';
|
||||
export * from '../test/generated-wrappers/i_dydx_bridge';
|
||||
export * from '../test/generated-wrappers/i_erc20_bridge';
|
||||
|
@@ -4,6 +4,7 @@
|
||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||
"files": [
|
||||
"generated-artifacts/ChaiBridge.json",
|
||||
"generated-artifacts/CurveBridge.json",
|
||||
"generated-artifacts/DydxBridge.json",
|
||||
"generated-artifacts/ERC1155Proxy.json",
|
||||
"generated-artifacts/ERC20BridgeProxy.json",
|
||||
@@ -15,6 +16,7 @@
|
||||
"generated-artifacts/IAssetProxyDispatcher.json",
|
||||
"generated-artifacts/IAuthorizable.json",
|
||||
"generated-artifacts/IChai.json",
|
||||
"generated-artifacts/ICurve.json",
|
||||
"generated-artifacts/IDydx.json",
|
||||
"generated-artifacts/IDydxBridge.json",
|
||||
"generated-artifacts/IERC20Bridge.json",
|
||||
@@ -37,6 +39,7 @@
|
||||
"generated-artifacts/TestUniswapBridge.json",
|
||||
"generated-artifacts/UniswapBridge.json",
|
||||
"test/generated-artifacts/ChaiBridge.json",
|
||||
"test/generated-artifacts/CurveBridge.json",
|
||||
"test/generated-artifacts/DydxBridge.json",
|
||||
"test/generated-artifacts/ERC1155Proxy.json",
|
||||
"test/generated-artifacts/ERC20BridgeProxy.json",
|
||||
@@ -48,6 +51,7 @@
|
||||
"test/generated-artifacts/IAssetProxyDispatcher.json",
|
||||
"test/generated-artifacts/IAuthorizable.json",
|
||||
"test/generated-artifacts/IChai.json",
|
||||
"test/generated-artifacts/ICurve.json",
|
||||
"test/generated-artifacts/IDydx.json",
|
||||
"test/generated-artifacts/IDydxBridge.json",
|
||||
"test/generated-artifacts/IERC20Bridge.json",
|
||||
|
@@ -1,4 +1,32 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "1.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "1.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Added decoders for broker data",
|
||||
"pr": 2484
|
||||
}
|
||||
],
|
||||
"timestamp": 1581748629
|
||||
},
|
||||
{
|
||||
"timestamp": 1581204851,
|
||||
"version": "1.0.2",
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.1.2 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.1 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.0 - _February 15, 2020_
|
||||
|
||||
* Added decoders for broker data (#2484)
|
||||
|
||||
## v1.0.2 - _February 8, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-broker",
|
||||
"version": "1.0.2",
|
||||
"version": "1.1.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -51,20 +51,20 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-asset-proxy": "^3.2.0",
|
||||
"@0x/contracts-erc20": "^3.1.0",
|
||||
"@0x/contracts-erc721": "^3.1.0",
|
||||
"@0x/contracts-exchange": "^3.2.0",
|
||||
"@0x/contracts-exchange-libs": "^4.3.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-asset-proxy": "^3.2.3",
|
||||
"@0x/contracts-erc20": "^3.1.3",
|
||||
"@0x/contracts-erc721": "^3.1.3",
|
||||
"@0x/contracts-exchange": "^3.2.3",
|
||||
"@0x/contracts-exchange-libs": "^4.3.3",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "*",
|
||||
@@ -84,10 +84,10 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0",
|
||||
"@0x/order-utils": "^10.2.0",
|
||||
"@0x/base-contract": "^6.2.1",
|
||||
"@0x/order-utils": "^10.2.2",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"ethereum-types": "^3.1.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,42 +1,59 @@
|
||||
import { assetDataUtils } from '@0x/order-utils';
|
||||
import { ERC1155AssetData } from '@0x/types';
|
||||
import { AbiEncoder, BigNumber } from '@0x/utils';
|
||||
|
||||
export const godsUnchainedUtils = {
|
||||
/**
|
||||
* Encodes the given proto and quality into the bytes format expected by the GodsUnchainedValidator.
|
||||
*/
|
||||
encodePropertyData(proto: BigNumber, quality: BigNumber): string {
|
||||
return AbiEncoder.create([{ name: 'proto', type: 'uint16' }, { name: 'quality', type: 'uint8' }]).encode({
|
||||
proto,
|
||||
quality,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Encodes the given proto and quality into ERC1155 asset data to be used as the takerAssetData
|
||||
* of a property-based GodsUnchained order. Must also provide the addresses of the Broker,
|
||||
* GodsUnchained, and GodsUnchainedValidator contracts. The optional bundleSize parameter specifies
|
||||
* how many cards are expected for each "unit" of the takerAssetAmount. For example, If the
|
||||
* takerAssetAmount is 3 and the bundleSize is 2, the taker must provide 2, 4, or 6 cards
|
||||
* with the given proto and quality to fill the order. If an odd number is provided, the fill fails.
|
||||
*/
|
||||
encodeBrokerAssetData(
|
||||
brokerAddress: string,
|
||||
godsUnchainedAddress: string,
|
||||
validatorAddress: string,
|
||||
proto: BigNumber,
|
||||
quality: BigNumber,
|
||||
bundleSize: number = 1,
|
||||
): string {
|
||||
const dataEncoder = AbiEncoder.create([
|
||||
{ name: 'godsUnchainedAddress', type: 'address' },
|
||||
{ name: 'validatorAddress', type: 'address' },
|
||||
{ name: 'propertyData', type: 'bytes' },
|
||||
]);
|
||||
const propertyData = AbiEncoder.create([
|
||||
{ name: 'proto', type: 'uint16' },
|
||||
{ name: 'quality', type: 'uint8' },
|
||||
]).encode({ proto, quality });
|
||||
const data = dataEncoder.encode({ godsUnchainedAddress, validatorAddress, propertyData });
|
||||
return assetDataUtils.encodeERC1155AssetData(brokerAddress, [], [new BigNumber(bundleSize)], data);
|
||||
},
|
||||
};
|
||||
export interface GodsUnchainedProperties {
|
||||
proto: BigNumber | number;
|
||||
quality: BigNumber | number;
|
||||
}
|
||||
|
||||
const propertyDataEncoder = AbiEncoder.create([{ name: 'proto', type: 'uint16' }, { name: 'quality', type: 'uint8' }]);
|
||||
const brokerDataEncoder = AbiEncoder.create([
|
||||
{ name: 'godsUnchainedAddress', type: 'address' },
|
||||
{ name: 'validatorAddress', type: 'address' },
|
||||
{ name: 'propertyData', type: 'bytes' },
|
||||
]);
|
||||
|
||||
/**
|
||||
* Encodes the given proto and quality into the bytes format expected by the GodsUnchainedValidator.
|
||||
*/
|
||||
export function encodePropertyData(properties: GodsUnchainedProperties): string {
|
||||
return propertyDataEncoder.encode(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the given proto and quality into ERC1155 asset data to be used as the takerAssetData
|
||||
* of a property-based GodsUnchained order. Must also provide the addresses of the Broker,
|
||||
* GodsUnchained, and GodsUnchainedValidator contracts. The optional bundleSize parameter specifies
|
||||
* how many cards are expected for each "unit" of the takerAssetAmount. For example, If the
|
||||
* takerAssetAmount is 3 and the bundleSize is 2, the taker must provide 2, 4, or 6 cards
|
||||
* with the given proto and quality to fill the order. If an odd number is provided, the fill fails.
|
||||
*/
|
||||
export function encodeBrokerAssetData(
|
||||
brokerAddress: string,
|
||||
godsUnchainedAddress: string,
|
||||
validatorAddress: string,
|
||||
properties: GodsUnchainedProperties,
|
||||
bundleSize: number = 1,
|
||||
): string {
|
||||
const propertyData = propertyDataEncoder.encode(properties);
|
||||
const brokerData = brokerDataEncoder.encode({ godsUnchainedAddress, validatorAddress, propertyData });
|
||||
return assetDataUtils.encodeERC1155AssetData(brokerAddress, [], [new BigNumber(bundleSize)], brokerData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes proto and quality from the bytes format expected by the GodsUnchainedValidator.
|
||||
*/
|
||||
export function decodePropertyData(propertyData: string): GodsUnchainedProperties {
|
||||
return propertyDataEncoder.decode(propertyData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes proto and quality from the ERC1155 takerAssetData of a property-based GodsUnchained order.
|
||||
*/
|
||||
export function decodeBrokerAssetData(brokerAssetData: string): GodsUnchainedProperties {
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const { callbackData: brokerData } = assetDataUtils.decodeAssetDataOrThrow(brokerAssetData) as ERC1155AssetData;
|
||||
const { propertyData } = brokerDataEncoder.decode(brokerData);
|
||||
return decodePropertyData(propertyData);
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
export { artifacts } from './artifacts';
|
||||
export { BrokerContract, GodsUnchainedValidatorContract, TestGodsUnchainedContract } from './wrappers';
|
||||
export { godsUnchainedUtils } from './gods_unchained_utils';
|
||||
export * from './gods_unchained_utils';
|
||||
export { BrokerRevertErrors } from '@0x/utils';
|
||||
export {
|
||||
ContractArtifact,
|
||||
|
@@ -2,7 +2,7 @@ import { blockchainTests, constants, expect, getRandomInteger } from '@0x/contra
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { godsUnchainedUtils } from '../src/gods_unchained_utils';
|
||||
import { encodePropertyData } from '../src/gods_unchained_utils';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { GodsUnchainedValidatorContract, TestGodsUnchainedContract } from './wrappers';
|
||||
@@ -33,7 +33,7 @@ blockchainTests.resets('GodsUnchainedValidator unit tests', env => {
|
||||
describe('checkBrokerAsset', () => {
|
||||
const proto = new BigNumber(42);
|
||||
const quality = new BigNumber(7);
|
||||
const propertyData = godsUnchainedUtils.encodePropertyData(proto, quality);
|
||||
const propertyData = encodePropertyData({ proto, quality });
|
||||
|
||||
it('succeeds if assetData proto and quality match propertyData', async () => {
|
||||
const tokenId = getRandomInteger(0, constants.MAX_UINT256);
|
||||
|
@@ -1,4 +1,31 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "3.1.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "3.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1581748629,
|
||||
"version": "3.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "3.1.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.3 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.2 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.1 - _February 15, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.0 - _February 8, 2020_
|
||||
|
||||
* Update tests. (#2462)
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"artifactsDir": "./test/generated-artifacts",
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-coordinator",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,19 +52,19 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-asset-proxy": "^3.2.0",
|
||||
"@0x/contracts-dev-utils": "^1.1.0",
|
||||
"@0x/contracts-erc20": "^3.1.0",
|
||||
"@0x/contracts-exchange": "^3.2.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/order-utils": "^10.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-asset-proxy": "^3.2.3",
|
||||
"@0x/contracts-dev-utils": "^1.3.1",
|
||||
"@0x/contracts-erc20": "^3.1.3",
|
||||
"@0x/contracts-exchange": "^3.2.3",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/order-utils": "^10.2.2",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "*",
|
||||
@@ -84,14 +84,14 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/assert": "^3.0.6",
|
||||
"@0x/base-contract": "^6.2.0",
|
||||
"@0x/contract-addresses": "^4.5.0",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/json-schemas": "^5.0.6",
|
||||
"@0x/assert": "^3.0.7",
|
||||
"@0x/base-contract": "^6.2.1",
|
||||
"@0x/contract-addresses": "^4.7.0",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/json-schemas": "^5.0.7",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"ethereum-types": "^3.1.0",
|
||||
"http-status-codes": "^1.3.2"
|
||||
},
|
||||
|
@@ -1,4 +1,41 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "1.3.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.3.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Update `DevUtils` addresses in `DeploymentConstants`",
|
||||
"pr": 2493
|
||||
}
|
||||
],
|
||||
"timestamp": 1582623685
|
||||
},
|
||||
{
|
||||
"version": "1.2.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add `DydxBridge` order validation",
|
||||
"pr": 2466
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1581748629,
|
||||
"version": "1.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.3.1 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.3.0 - _February 25, 2020_
|
||||
|
||||
* Update `DevUtils` addresses in `DeploymentConstants` (#2493)
|
||||
|
||||
## v1.2.0 - _Invalid date_
|
||||
|
||||
* Add `DydxBridge` order validation (#2466)
|
||||
|
||||
## v1.1.1 - _February 15, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.0 - _February 8, 2020_
|
||||
|
||||
* Refactor mixins into public libraries. (#2464)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -34,15 +34,18 @@ contract Addresses is
|
||||
address public erc1155ProxyAddress;
|
||||
address public staticCallProxyAddress;
|
||||
address public chaiBridgeAddress;
|
||||
address public dydxBridgeAddress;
|
||||
|
||||
constructor (
|
||||
address exchange_,
|
||||
address chaiBridge_
|
||||
address chaiBridge_,
|
||||
address dydxBridge_
|
||||
)
|
||||
public
|
||||
{
|
||||
exchangeAddress = exchange_;
|
||||
chaiBridgeAddress = chaiBridge_;
|
||||
dydxBridgeAddress = dydxBridge_;
|
||||
erc20ProxyAddress = IExchange(exchange_).getAssetProxy(IAssetData(address(0)).ERC20Token.selector);
|
||||
erc721ProxyAddress = IExchange(exchange_).getAssetProxy(IAssetData(address(0)).ERC721Token.selector);
|
||||
erc1155ProxyAddress = IExchange(exchange_).getAssetProxy(IAssetData(address(0)).ERC1155Assets.selector);
|
||||
|
@@ -28,7 +28,7 @@ import "@0x/contracts-erc1155/contracts/src/interfaces/IERC1155.sol";
|
||||
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IChai.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
|
||||
import "./Addresses.sol";
|
||||
import "./LibAssetData.sol";
|
||||
import "./LibDydxBalance.sol";
|
||||
|
||||
|
||||
contract AssetBalance is
|
||||
@@ -269,11 +269,14 @@ contract AssetBalance is
|
||||
|
||||
} else if (assetProxyId == IAssetData(address(0)).ERC20Bridge.selector) {
|
||||
// Get address of ERC20 token and bridge contract
|
||||
(, address tokenAddress, address bridgeAddress,) = LibAssetData.decodeERC20BridgeAssetData(assetData);
|
||||
(, address tokenAddress, address bridgeAddress,) =
|
||||
LibAssetData.decodeERC20BridgeAssetData(assetData);
|
||||
if (tokenAddress == _getDaiAddress() && bridgeAddress == chaiBridgeAddress) {
|
||||
uint256 chaiAllowance = LibERC20Token.allowance(_getChaiAddress(), ownerAddress, chaiBridgeAddress);
|
||||
// Dai allowance is unlimited if Chai allowance is unlimited
|
||||
allowance = chaiAllowance == _MAX_UINT256 ? _MAX_UINT256 : _convertChaiToDaiAmount(chaiAllowance);
|
||||
} else if (bridgeAddress == dydxBridgeAddress) {
|
||||
allowance = LibDydxBalance.getDydxMakerAllowance(ownerAddress, bridgeAddress, _getDydxAddress());
|
||||
}
|
||||
// Allowance will be 0 if bridge is not supported
|
||||
}
|
||||
@@ -366,6 +369,17 @@ contract AssetBalance is
|
||||
if (order.makerAssetData.length < 4) {
|
||||
return (0, 0);
|
||||
}
|
||||
bytes4 assetProxyId = order.makerAssetData.readBytes4(0);
|
||||
// Handle dydx bridge assets.
|
||||
if (assetProxyId == IAssetData(address(0)).ERC20Bridge.selector) {
|
||||
(, , address bridgeAddress, ) = LibAssetData.decodeERC20BridgeAssetData(order.makerAssetData);
|
||||
if (bridgeAddress == dydxBridgeAddress) {
|
||||
return (
|
||||
LibDydxBalance.getDydxMakerBalance(order, _getDydxAddress()),
|
||||
getAssetProxyAllowance(order.makerAddress, order.makerAssetData)
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
getBalance(order.makerAddress, order.makerAssetData),
|
||||
getAssetProxyAllowance(order.makerAddress, order.makerAssetData)
|
||||
|
@@ -40,12 +40,14 @@ contract DevUtils is
|
||||
{
|
||||
constructor (
|
||||
address exchange_,
|
||||
address chaiBridge_
|
||||
address chaiBridge_,
|
||||
address dydxBridge_
|
||||
)
|
||||
public
|
||||
Addresses(
|
||||
exchange_,
|
||||
chaiBridge_
|
||||
chaiBridge_,
|
||||
dydxBridge_
|
||||
)
|
||||
LibEIP712ExchangeDomain(uint256(0), address(0)) // null args because because we only use constants
|
||||
{}
|
||||
|
436
contracts/dev-utils/contracts/src/LibDydxBalance.sol
Normal file
436
contracts/dev-utils/contracts/src/LibDydxBalance.sol
Normal file
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.16;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetData.sol";
|
||||
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IDydxBridge.sol";
|
||||
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IDydx.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
|
||||
import "@0x/contracts-utils/contracts/src/D18.sol";
|
||||
import "./LibAssetData.sol";
|
||||
|
||||
|
||||
library LibDydxBalance {
|
||||
|
||||
using LibBytes for bytes;
|
||||
using LibSafeMath for uint256;
|
||||
|
||||
/// @dev Padding % added to the minimum collateralization ratio to
|
||||
/// prevent withdrawing exactly the amount that would make an account
|
||||
/// insolvent. 1 bps.
|
||||
int256 private constant MARGIN_RATIO_PADDING = 0.0001e18;
|
||||
|
||||
/// @dev Structure that holds all pertinent info needed to perform a balance
|
||||
/// check.
|
||||
struct BalanceCheckInfo {
|
||||
IDydx dydx;
|
||||
address bridgeAddress;
|
||||
address makerAddress;
|
||||
address makerTokenAddress;
|
||||
address takerTokenAddress;
|
||||
int256 orderMakerToTakerRate;
|
||||
uint256[] accounts;
|
||||
IDydxBridge.BridgeAction[] actions;
|
||||
}
|
||||
|
||||
/// @dev Gets the maker asset allowance for a Dydx bridge order.
|
||||
/// @param makerAddress The maker of the order.
|
||||
/// @param bridgeAddress The address of the Dydx bridge.
|
||||
/// @param dydx The Dydx contract address.
|
||||
/// @return allowance The maker asset allowance.
|
||||
function getDydxMakerAllowance(address makerAddress, address bridgeAddress, address dydx)
|
||||
public
|
||||
view
|
||||
returns (uint256 allowance)
|
||||
{
|
||||
// Allowance is infinite if the dydx bridge is an operator for the maker.
|
||||
return IDydx(dydx).getIsLocalOperator(makerAddress, bridgeAddress)
|
||||
? uint256(-1) : 0;
|
||||
}
|
||||
|
||||
/// @dev Gets the maker allowance for a
|
||||
/// @dev Get the maker asset balance of an order with a `DydxBridge` maker asset.
|
||||
/// @param order An order with a dydx maker asset.
|
||||
/// @param dydx The address of the dydx contract.
|
||||
/// @return balance The maker asset balance.
|
||||
function getDydxMakerBalance(LibOrder.Order memory order, address dydx)
|
||||
public
|
||||
view
|
||||
returns (uint256 balance)
|
||||
{
|
||||
BalanceCheckInfo memory info = _getBalanceCheckInfo(order, dydx);
|
||||
// Actions must be well-formed.
|
||||
if (!_areActionsWellFormed(info)) {
|
||||
return 0;
|
||||
}
|
||||
// If the rate we withdraw maker tokens is less than one, the asset
|
||||
// proxy will throw because we will always transfer less maker tokens
|
||||
// than asked.
|
||||
if (_getMakerTokenWithdrawRate(info) < D18.one()) {
|
||||
return 0;
|
||||
}
|
||||
// The maker balance is the smaller of:
|
||||
return LibSafeMath.min256(
|
||||
// How many times we can execute all the deposit actions.
|
||||
_getDepositableMakerAmount(info),
|
||||
// How many times we can execute all the actions before the an
|
||||
// account becomes undercollateralized.
|
||||
_getSolventMakerAmount(info)
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Checks that:
|
||||
/// 1. Actions are arranged as [...deposits, withdraw].
|
||||
/// 2. There is only one deposit for each market ID.
|
||||
/// 3. Every action has a valid account index.
|
||||
/// 4. There is exactly one withdraw at the end and it is for the
|
||||
/// maker token.
|
||||
/// @param info State from `_getBalanceCheckInfo()`.
|
||||
/// @return areWellFormed Whether the actions are well-formed.
|
||||
function _areActionsWellFormed(BalanceCheckInfo memory info)
|
||||
internal
|
||||
view
|
||||
returns (bool areWellFormed)
|
||||
{
|
||||
if (info.actions.length == 0) {
|
||||
return false;
|
||||
}
|
||||
uint256 depositCount = 0;
|
||||
// Count the number of deposits.
|
||||
for (; depositCount < info.actions.length; ++depositCount) {
|
||||
IDydxBridge.BridgeAction memory action = info.actions[depositCount];
|
||||
if (action.actionType != IDydxBridge.BridgeActionType.Deposit) {
|
||||
break;
|
||||
}
|
||||
// Search all prior actions for the same market ID.
|
||||
uint256 marketId = action.marketId;
|
||||
for (uint256 j = 0; j < depositCount; ++j) {
|
||||
if (info.actions[j].marketId == marketId) {
|
||||
// Market ID is not unique.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Check that the account index is within the valid range.
|
||||
if (action.accountIdx >= info.accounts.length) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// There must be exactly one withdraw action at the end.
|
||||
if (depositCount + 1 != info.actions.length) {
|
||||
return false;
|
||||
}
|
||||
IDydxBridge.BridgeAction memory withdraw = info.actions[depositCount];
|
||||
if (withdraw.actionType != IDydxBridge.BridgeActionType.Withdraw) {
|
||||
return false;
|
||||
}
|
||||
// And it must be for the maker token.
|
||||
if (info.dydx.getMarketTokenAddress(withdraw.marketId) != info.makerTokenAddress) {
|
||||
return false;
|
||||
}
|
||||
// Check the account index.
|
||||
return withdraw.accountIdx < info.accounts.length;
|
||||
}
|
||||
|
||||
/// @dev Returns the rate at which we withdraw maker tokens.
|
||||
/// @param info State from `_getBalanceCheckInfo()`.
|
||||
/// @return makerTokenWithdrawRate Maker token withdraw rate.
|
||||
function _getMakerTokenWithdrawRate(BalanceCheckInfo memory info)
|
||||
internal
|
||||
pure
|
||||
returns (int256 makerTokenWithdrawRate)
|
||||
{
|
||||
// The last action is always a withdraw for the maker token.
|
||||
IDydxBridge.BridgeAction memory withdraw = info.actions[info.actions.length - 1];
|
||||
return _getActionRate(withdraw);
|
||||
}
|
||||
|
||||
/// @dev Get how much maker asset we can transfer before a deposit fails.
|
||||
/// @param info State from `_getBalanceCheckInfo()`.
|
||||
function _getDepositableMakerAmount(BalanceCheckInfo memory info)
|
||||
internal
|
||||
view
|
||||
returns (uint256 depositableMakerAmount)
|
||||
{
|
||||
depositableMakerAmount = uint256(-1);
|
||||
// Take the minimum maker amount from all deposits.
|
||||
for (uint256 i = 0; i < info.actions.length; ++i) {
|
||||
IDydxBridge.BridgeAction memory action = info.actions[i];
|
||||
// Only looking at deposit actions.
|
||||
if (action.actionType != IDydxBridge.BridgeActionType.Deposit) {
|
||||
continue;
|
||||
}
|
||||
// `depositRate` is the rate at which we convert a maker token into
|
||||
// a taker token for deposit.
|
||||
int256 depositRate = _getActionRate(action);
|
||||
// Taker tokens will be transferred to the maker for every fill, so
|
||||
// we reduce the effective deposit rate if we're depositing the taker
|
||||
// token.
|
||||
address depositToken = info.dydx.getMarketTokenAddress(action.marketId);
|
||||
if (info.takerTokenAddress != address(0) && depositToken == info.takerTokenAddress) {
|
||||
depositRate = D18.sub(depositRate, info.orderMakerToTakerRate);
|
||||
}
|
||||
// If the deposit rate is > 0, we are limited by the transferrable
|
||||
// token balance of the maker.
|
||||
if (depositRate > 0) {
|
||||
uint256 supply = _getTransferabeTokenAmount(
|
||||
depositToken,
|
||||
info.makerAddress,
|
||||
address(info.dydx)
|
||||
);
|
||||
depositableMakerAmount = LibSafeMath.min256(
|
||||
depositableMakerAmount,
|
||||
uint256(D18.div(supply, depositRate))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Get how much maker asset we can transfer before an account
|
||||
/// becomes insolvent.
|
||||
/// @param info State from `_getBalanceCheckInfo()`.
|
||||
function _getSolventMakerAmount(BalanceCheckInfo memory info)
|
||||
internal
|
||||
view
|
||||
returns (uint256 solventMakerAmount)
|
||||
{
|
||||
solventMakerAmount = uint256(-1);
|
||||
assert(info.actions.length >= 1);
|
||||
IDydxBridge.BridgeAction memory withdraw = info.actions[info.actions.length - 1];
|
||||
assert(withdraw.actionType == IDydxBridge.BridgeActionType.Withdraw);
|
||||
int256 minCr = D18.add(_getMinimumCollateralizationRatio(info.dydx), MARGIN_RATIO_PADDING);
|
||||
// Loop through the accounts.
|
||||
for (uint256 accountIdx = 0; accountIdx < info.accounts.length; ++accountIdx) {
|
||||
(uint256 supplyValue, uint256 borrowValue) =
|
||||
_getAccountMarketValues(info, info.accounts[accountIdx]);
|
||||
// All accounts must currently be solvent.
|
||||
if (borrowValue != 0 && D18.div(supplyValue, borrowValue) < minCr) {
|
||||
return 0;
|
||||
}
|
||||
// If this is the same account used to in the withdraw/borrow action,
|
||||
// compute the maker amount at which it will become insolvent.
|
||||
if (accountIdx != withdraw.accountIdx) {
|
||||
continue;
|
||||
}
|
||||
// Compute the deposit/collateralization rate, which is the rate at
|
||||
// which (USD) value is added to the account across all markets.
|
||||
int256 dd = 0;
|
||||
for (uint256 i = 0; i < info.actions.length - 1; ++i) {
|
||||
IDydxBridge.BridgeAction memory deposit = info.actions[i];
|
||||
assert(deposit.actionType == IDydxBridge.BridgeActionType.Deposit);
|
||||
if (deposit.accountIdx == accountIdx) {
|
||||
dd = D18.add(
|
||||
dd,
|
||||
_getActionRateValue(
|
||||
info,
|
||||
deposit
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
// Compute the borrow/withdraw rate, which is the rate at which
|
||||
// (USD) value is deducted from the account.
|
||||
int256 db = _getActionRateValue(
|
||||
info,
|
||||
withdraw
|
||||
);
|
||||
// If the deposit to withdraw ratio is >= the minimum collateralization
|
||||
// ratio, then we will never become insolvent at these prices.
|
||||
if (D18.div(dd, db) >= minCr) {
|
||||
continue;
|
||||
}
|
||||
// If the adjusted deposit rates are equal, the account will remain
|
||||
// at the same level of collateralization.
|
||||
if (D18.mul(minCr, db) == dd) {
|
||||
continue;
|
||||
}
|
||||
// The collateralization ratio for this account, parameterized by
|
||||
// `t` (maker amount), is given by:
|
||||
// `cr = (supplyValue + t * dd) / (borrowValue + t * db)`
|
||||
// Solving for `t` gives us:
|
||||
// `t = (supplyValue - cr * borrowValue) / (cr * db - dd)`
|
||||
int256 t = D18.div(
|
||||
D18.sub(supplyValue, D18.mul(minCr, borrowValue)),
|
||||
D18.sub(D18.mul(minCr, db), dd)
|
||||
);
|
||||
solventMakerAmount = LibSafeMath.min256(
|
||||
solventMakerAmount,
|
||||
// `t` is in maker token units, so convert it to maker wei.
|
||||
_toWei(info.makerTokenAddress, uint256(D18.clip(t)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Create a `BalanceCheckInfo` struct.
|
||||
/// @param order An order with a `DydxBridge` maker asset.
|
||||
/// @param dydx The address of the Dydx contract.
|
||||
/// @return info The `BalanceCheckInfo` struct.
|
||||
function _getBalanceCheckInfo(LibOrder.Order memory order, address dydx)
|
||||
private
|
||||
pure
|
||||
returns (BalanceCheckInfo memory info)
|
||||
{
|
||||
bytes memory rawBridgeData;
|
||||
(, info.makerTokenAddress, info.bridgeAddress, rawBridgeData) =
|
||||
LibAssetData.decodeERC20BridgeAssetData(order.makerAssetData);
|
||||
info.dydx = IDydx(dydx);
|
||||
info.makerAddress = order.makerAddress;
|
||||
if (order.takerAssetData.length == 36) {
|
||||
if (order.takerAssetData.readBytes4(0) == IAssetData(0).ERC20Token.selector) {
|
||||
(, info.takerTokenAddress) =
|
||||
LibAssetData.decodeERC20AssetData(order.takerAssetData);
|
||||
}
|
||||
}
|
||||
info.orderMakerToTakerRate = D18.div(order.takerAssetAmount, order.makerAssetAmount);
|
||||
(IDydxBridge.BridgeData memory bridgeData) =
|
||||
abi.decode(rawBridgeData, (IDydxBridge.BridgeData));
|
||||
info.accounts = bridgeData.accountNumbers;
|
||||
info.actions = bridgeData.actions;
|
||||
}
|
||||
|
||||
/// @dev Returns the conversion rate for an action.
|
||||
/// @param action A `BridgeAction`.
|
||||
function _getActionRate(IDydxBridge.BridgeAction memory action)
|
||||
private
|
||||
pure
|
||||
returns (int256 rate)
|
||||
{
|
||||
rate = action.conversionRateDenominator == 0
|
||||
? D18.one()
|
||||
: D18.div(
|
||||
action.conversionRateNumerator,
|
||||
action.conversionRateDenominator
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Returns the USD value of an action based on its conversion rate
|
||||
/// and market prices.
|
||||
/// @param info State from `_getBalanceCheckInfo()`.
|
||||
/// @param action A `BridgeAction`.
|
||||
function _getActionRateValue(
|
||||
BalanceCheckInfo memory info,
|
||||
IDydxBridge.BridgeAction memory action
|
||||
)
|
||||
private
|
||||
view
|
||||
returns (int256 value)
|
||||
{
|
||||
address toToken = info.dydx.getMarketTokenAddress(action.marketId);
|
||||
uint256 fromTokenDecimals = LibERC20Token.decimals(info.makerTokenAddress);
|
||||
uint256 toTokenDecimals = LibERC20Token.decimals(toToken);
|
||||
// First express the rate as 18-decimal units.
|
||||
value = toTokenDecimals > fromTokenDecimals
|
||||
? int256(
|
||||
uint256(_getActionRate(action))
|
||||
.safeDiv(10 ** (toTokenDecimals - fromTokenDecimals))
|
||||
)
|
||||
: int256(
|
||||
uint256(_getActionRate(action))
|
||||
.safeMul(10 ** (fromTokenDecimals - toTokenDecimals))
|
||||
);
|
||||
// Prices have 18 + (18 - TOKEN_DECIMALS) decimal places because
|
||||
// consistency is stupid.
|
||||
uint256 price = info.dydx.getMarketPrice(action.marketId).value;
|
||||
// Make prices have 18 decimals.
|
||||
if (toTokenDecimals > 18) {
|
||||
price = price.safeMul(10 ** (toTokenDecimals - 18));
|
||||
} else {
|
||||
price = price.safeDiv(10 ** (18 - toTokenDecimals));
|
||||
}
|
||||
// The action value is the action rate times the price.
|
||||
value = D18.mul(price, value);
|
||||
// Scale by the market premium.
|
||||
int256 marketPremium = D18.add(
|
||||
D18.one(),
|
||||
info.dydx.getMarketMarginPremium(action.marketId).value
|
||||
);
|
||||
if (action.actionType == IDydxBridge.BridgeActionType.Deposit) {
|
||||
value = D18.div(value, marketPremium);
|
||||
} else {
|
||||
value = D18.mul(value, marketPremium);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Convert a `D18` fraction of 1 token to the equivalent integer wei.
|
||||
/// @param token Address the of the token.
|
||||
/// @param units Token units expressed with 18 digit precision.
|
||||
function _toWei(address token, uint256 units)
|
||||
private
|
||||
view
|
||||
returns (uint256 rate)
|
||||
{
|
||||
uint256 decimals = LibERC20Token.decimals(token);
|
||||
rate = decimals > 18
|
||||
? units.safeMul(10 ** (decimals - 18))
|
||||
: units.safeDiv(10 ** (18 - decimals));
|
||||
}
|
||||
|
||||
/// @dev Get the global minimum collateralization ratio required for
|
||||
/// an account to be considered solvent.
|
||||
/// @param dydx The Dydx interface.
|
||||
function _getMinimumCollateralizationRatio(IDydx dydx)
|
||||
private
|
||||
view
|
||||
returns (int256 ratio)
|
||||
{
|
||||
IDydx.RiskParams memory riskParams = dydx.getRiskParams();
|
||||
return D18.add(D18.one(), D18.toSigned(riskParams.marginRatio.value));
|
||||
}
|
||||
|
||||
/// @dev Get the total supply and borrow values for an account across all markets.
|
||||
/// @param info State from `_getBalanceCheckInfo()`.
|
||||
/// @param account The Dydx account identifier.
|
||||
function _getAccountMarketValues(BalanceCheckInfo memory info, uint256 account)
|
||||
private
|
||||
view
|
||||
returns (uint256 supplyValue, uint256 borrowValue)
|
||||
{
|
||||
(IDydx.Value memory supplyValue_, IDydx.Value memory borrowValue_) =
|
||||
info.dydx.getAdjustedAccountValues(IDydx.AccountInfo(
|
||||
info.makerAddress,
|
||||
account
|
||||
));
|
||||
// Account values have 36 decimal places because dydx likes to make sure
|
||||
// you're paying attention.
|
||||
return (supplyValue_.value / 1e18, borrowValue_.value / 1e18);
|
||||
}
|
||||
|
||||
/// @dev Get the amount of an ERC20 token held by `owner` that can be transferred
|
||||
/// by `spender`.
|
||||
/// @param tokenAddress The address of the ERC20 token.
|
||||
/// @param owner The address of the token holder.
|
||||
/// @param spender The address of the token spender.
|
||||
function _getTransferabeTokenAmount(
|
||||
address tokenAddress,
|
||||
address owner,
|
||||
address spender
|
||||
)
|
||||
private
|
||||
view
|
||||
returns (uint256 transferableAmount)
|
||||
{
|
||||
return LibSafeMath.min256(
|
||||
LibERC20Token.allowance(tokenAddress, owner, spender),
|
||||
LibERC20Token.balanceOf(tokenAddress, owner)
|
||||
);
|
||||
}
|
||||
}
|
@@ -118,22 +118,14 @@ contract OrderValidationUtils is
|
||||
transferableTakerAssetAmount
|
||||
);
|
||||
|
||||
// Execute the maker transfers.
|
||||
fillableTakerAssetAmount = LibOrderTransferSimulation.getSimulatedOrderMakerTransferResults(
|
||||
exchangeAddress,
|
||||
order,
|
||||
order.takerAddress,
|
||||
fillableTakerAssetAmount
|
||||
) == LibOrderTransferSimulation.OrderTransferResults.TransfersSuccessful ? fillableTakerAssetAmount : 0;
|
||||
|
||||
if (!_isAssetDataValid(order.takerAssetData)) {
|
||||
fillableTakerAssetAmount = 0;
|
||||
}
|
||||
|
||||
if (order.takerFee != 0 && !_isAssetDataValid(order.takerFeeAssetData)) {
|
||||
// Ensure that all of the asset data is valid. Fee asset data only needs
|
||||
// to be valid if the fees are nonzero.
|
||||
if (!_areOrderAssetDatasValid(order)) {
|
||||
fillableTakerAssetAmount = 0;
|
||||
}
|
||||
|
||||
// If the order is not fillable, then the fillable taker asset amount is
|
||||
// zero by definition.
|
||||
if (orderInfo.orderStatus != LibOrder.OrderStatus.FILLABLE) {
|
||||
fillableTakerAssetAmount = 0;
|
||||
}
|
||||
@@ -207,7 +199,22 @@ contract OrderValidationUtils is
|
||||
{
|
||||
(uint256 balance, uint256 allowance) = _getConvertibleMakerBalanceAndAssetProxyAllowance(order);
|
||||
transferableAssetAmount = LibSafeMath.min256(balance, allowance);
|
||||
return transferableAssetAmount;
|
||||
return LibSafeMath.min256(transferableAssetAmount, order.makerAssetAmount);
|
||||
}
|
||||
|
||||
/// @dev Checks that the asset data contained in a ZeroEx is valid and returns
|
||||
/// a boolean that indicates whether or not the asset data was found to be valid.
|
||||
/// @param order A ZeroEx order to validate.
|
||||
/// @return The validatity of the asset data.
|
||||
function _areOrderAssetDatasValid(LibOrder.Order memory order)
|
||||
internal
|
||||
pure
|
||||
returns (bool)
|
||||
{
|
||||
return _isAssetDataValid(order.makerAssetData) &&
|
||||
(order.makerFee == 0 || _isAssetDataValid(order.makerFeeAssetData)) &&
|
||||
_isAssetDataValid(order.takerAssetData) &&
|
||||
(order.takerFee == 0 || _isAssetDataValid(order.takerFeeAssetData));
|
||||
}
|
||||
|
||||
/// @dev This function handles the edge cases around taker validation. This function
|
||||
|
181
contracts/dev-utils/contracts/test/TestDydx.sol
Normal file
181
contracts/dev-utils/contracts/test/TestDydx.sol
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.16;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IDydx.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||
|
||||
|
||||
// solhint-disable separate-by-one-line-in-contract
|
||||
contract TestDydx {
|
||||
|
||||
struct OperatorConfig {
|
||||
address owner;
|
||||
address operator;
|
||||
}
|
||||
|
||||
struct AccountConfig {
|
||||
address owner;
|
||||
uint256 accountId;
|
||||
int256[] balances;
|
||||
}
|
||||
|
||||
struct MarketInfo {
|
||||
address token;
|
||||
uint256 price;
|
||||
}
|
||||
|
||||
struct TestConfig {
|
||||
uint256 marginRatio;
|
||||
OperatorConfig[] operators;
|
||||
AccountConfig[] accounts;
|
||||
MarketInfo[] markets;
|
||||
}
|
||||
|
||||
mapping (bytes32 => bool) private _operators;
|
||||
mapping (bytes32 => int256) private _balance;
|
||||
MarketInfo[] private _markets;
|
||||
uint256 private _marginRatio;
|
||||
|
||||
constructor(TestConfig memory config) public {
|
||||
_marginRatio = config.marginRatio;
|
||||
for (uint256 marketId = 0; marketId < config.markets.length; ++marketId) {
|
||||
_markets.push(config.markets[marketId]);
|
||||
}
|
||||
for (uint256 i = 0; i < config.operators.length; ++i) {
|
||||
OperatorConfig memory op = config.operators[i];
|
||||
_operators[_getOperatorHash(op.owner, op.operator)] = true;
|
||||
}
|
||||
for (uint256 i = 0; i < config.accounts.length; ++i) {
|
||||
AccountConfig memory acct = config.accounts[i];
|
||||
for (uint256 marketId = 0; marketId < acct.balances.length; ++marketId) {
|
||||
_balance[_getBalanceHash(acct.owner, acct.accountId, marketId)] =
|
||||
acct.balances[marketId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getIsLocalOperator(
|
||||
address owner,
|
||||
address operator
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bool isLocalOperator)
|
||||
{
|
||||
return _operators[_getOperatorHash(owner, operator)];
|
||||
}
|
||||
|
||||
function getMarketTokenAddress(
|
||||
uint256 marketId
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (address tokenAddress)
|
||||
{
|
||||
return _markets[marketId].token;
|
||||
}
|
||||
|
||||
function getRiskParams()
|
||||
external
|
||||
view
|
||||
returns (IDydx.RiskParams memory riskParams)
|
||||
{
|
||||
return IDydx.RiskParams({
|
||||
marginRatio: IDydx.D256(_marginRatio),
|
||||
liquidationSpread: IDydx.D256(0),
|
||||
earningsRate: IDydx.D256(0),
|
||||
minBorrowedValue: IDydx.Value(0)
|
||||
});
|
||||
}
|
||||
|
||||
function getAdjustedAccountValues(
|
||||
IDydx.AccountInfo calldata account
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (IDydx.Value memory supplyValue, IDydx.Value memory borrowValue)
|
||||
{
|
||||
for (uint256 marketId = 0; marketId < _markets.length; ++marketId) {
|
||||
int256 balance =
|
||||
_balance[_getBalanceHash(account.owner, account.number, marketId)];
|
||||
// Account values have 36 decimal places.
|
||||
// `getMarketPrice()` returns a unit with
|
||||
// 18 + (18 - TOKEN_DECIMALS) decimal places so multiplying the price
|
||||
// with the wei balance will result in a 36 decimal value.
|
||||
balance = balance * int256(getMarketPrice(marketId).value);
|
||||
if (balance >= 0) {
|
||||
supplyValue.value += uint256(balance);
|
||||
} else {
|
||||
borrowValue.value += uint256(-balance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getMarketMarginPremium(uint256)
|
||||
external
|
||||
view
|
||||
returns (IDydx.D256 memory premium)
|
||||
{
|
||||
// Return 0.
|
||||
return premium;
|
||||
}
|
||||
|
||||
function getMarketPrice(
|
||||
uint256 marketId
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (IDydx.Price memory price)
|
||||
{
|
||||
MarketInfo memory market = _markets[marketId];
|
||||
uint256 decimals = LibERC20Token.decimals(market.token);
|
||||
price.value = _markets[marketId].price;
|
||||
// Market prices have 18 + (18 - TOKEN_DECIMALS)
|
||||
if (decimals > 18) {
|
||||
price.value /= 10 ** (decimals - 18);
|
||||
} else {
|
||||
price.value *= 10 ** (18 - decimals);
|
||||
}
|
||||
}
|
||||
|
||||
function _getOperatorHash(address owner, address operator)
|
||||
private
|
||||
pure
|
||||
returns (bytes32 operatorHash)
|
||||
{
|
||||
return keccak256(abi.encode(
|
||||
owner,
|
||||
operator
|
||||
));
|
||||
}
|
||||
|
||||
function _getBalanceHash(address owner, uint256 accountId, uint256 marketId)
|
||||
private
|
||||
pure
|
||||
returns (bytes32 balanceHash)
|
||||
{
|
||||
return keccak256(abi.encode(
|
||||
owner,
|
||||
accountId,
|
||||
marketId
|
||||
));
|
||||
}
|
||||
}
|
116
contracts/dev-utils/contracts/test/TestLibDydxBalance.sol
Normal file
116
contracts/dev-utils/contracts/test/TestLibDydxBalance.sol
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.16;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../src/LibDydxBalance.sol";
|
||||
|
||||
|
||||
contract TestLibDydxBalanceToken {
|
||||
|
||||
uint8 public decimals;
|
||||
mapping (address => uint256) public balanceOf;
|
||||
mapping (address => mapping (address => uint256)) public allowance;
|
||||
|
||||
constructor(uint8 decimals_) public {
|
||||
decimals = decimals_;
|
||||
}
|
||||
|
||||
function setBalance(address owner, uint256 balance) external {
|
||||
balanceOf[owner] = balance;
|
||||
}
|
||||
|
||||
function setApproval(
|
||||
address owner,
|
||||
address spender,
|
||||
uint256 allowance_
|
||||
)
|
||||
external
|
||||
{
|
||||
allowance[owner][spender] = allowance_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract TestLibDydxBalance {
|
||||
|
||||
mapping (address => TestLibDydxBalanceToken) private tokens;
|
||||
|
||||
function createToken(uint8 decimals) external returns (address) {
|
||||
TestLibDydxBalanceToken token = new TestLibDydxBalanceToken(decimals);
|
||||
return address(tokens[address(token)] = token);
|
||||
}
|
||||
|
||||
function setTokenBalance(
|
||||
address tokenAddress,
|
||||
address owner,
|
||||
uint256 balance
|
||||
)
|
||||
external
|
||||
{
|
||||
tokens[tokenAddress].setBalance(owner, balance);
|
||||
}
|
||||
|
||||
function setTokenApproval(
|
||||
address tokenAddress,
|
||||
address owner,
|
||||
address spender,
|
||||
uint256 allowance
|
||||
)
|
||||
external
|
||||
{
|
||||
tokens[tokenAddress].setApproval(owner, spender, allowance);
|
||||
}
|
||||
|
||||
function getDydxMakerBalance(LibOrder.Order memory order, address dydx)
|
||||
public
|
||||
view
|
||||
returns (uint256 balance)
|
||||
{
|
||||
return LibDydxBalance.getDydxMakerBalance(order, dydx);
|
||||
}
|
||||
|
||||
function getSolventMakerAmount(
|
||||
LibDydxBalance.BalanceCheckInfo memory info
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (uint256 solventMakerAmount)
|
||||
{
|
||||
return LibDydxBalance._getSolventMakerAmount(info);
|
||||
}
|
||||
|
||||
function getDepositableMakerAmount(
|
||||
LibDydxBalance.BalanceCheckInfo memory info
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (uint256 depositableMakerAmount)
|
||||
{
|
||||
return LibDydxBalance._getDepositableMakerAmount(info);
|
||||
}
|
||||
|
||||
function areActionsWellFormed(LibDydxBalance.BalanceCheckInfo memory info)
|
||||
public
|
||||
view
|
||||
returns (bool areWellFormed)
|
||||
{
|
||||
return LibDydxBalance._areActionsWellFormed(info);
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-dev-utils",
|
||||
"version": "1.1.0",
|
||||
"version": "1.3.1",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -8,7 +8,7 @@
|
||||
"main": "lib/src/index.js",
|
||||
"scripts": {
|
||||
"build": "yarn pre_build && tsc -b",
|
||||
"test": "yarn assert_deployable",
|
||||
"test": "yarn assert_deployable && yarn mocha -t 10000 -b ./lib/test/**_test.js",
|
||||
"assert_deployable": "node -e \"const bytecodeLen = (require('./generated-artifacts/DevUtils.json').compilerOutput.evm.bytecode.object.length-2)/2; assert(bytecodeLen<=0x6000,'DevUtils contract is too big to deploy, per EIP-170. '+bytecodeLen+'>'+0x6000)\"",
|
||||
"build:ci": "yarn build",
|
||||
"pre_build": "run-s compile quantify_bytecode contracts:gen generate_contract_wrappers contracts:copy",
|
||||
@@ -27,8 +27,8 @@
|
||||
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||
},
|
||||
"config": {
|
||||
"publicInterfaceContracts": "DevUtils,LibAssetData,LibOrderTransferSimulation,LibTransactionDecoder",
|
||||
"abis": "./test/generated-artifacts/@(Addresses|AssetBalance|DevUtils|EthBalanceChecker|ExternalFunctions|LibAssetData|LibOrderTransferSimulation|LibTransactionDecoder|OrderTransferSimulationUtils|OrderValidationUtils).json",
|
||||
"publicInterfaceContracts": "DevUtils,LibAssetData,LibDydxBalance,LibOrderTransferSimulation,LibTransactionDecoder",
|
||||
"abis": "./test/generated-artifacts/@(Addresses|AssetBalance|DevUtils|EthBalanceChecker|ExternalFunctions|LibAssetData|LibDydxBalance|LibOrderTransferSimulation|LibTransactionDecoder|OrderTransferSimulationUtils|OrderValidationUtils|TestDydx|TestLibDydxBalance).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
@@ -41,17 +41,17 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/dev-utils/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/assert": "^3.0.6",
|
||||
"@0x/contracts-asset-proxy": "^3.2.0",
|
||||
"@0x/contracts-erc20": "^3.1.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/assert": "^3.0.7",
|
||||
"@0x/contracts-asset-proxy": "^3.2.3",
|
||||
"@0x/contracts-erc20": "^3.1.3",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"@types/node": "*",
|
||||
"ethereum-types": "^3.1.0",
|
||||
"ethers": "~4.0.4",
|
||||
@@ -64,7 +64,7 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0"
|
||||
"@0x/base-contract": "^6.2.1"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@@ -7,11 +7,13 @@ import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as DevUtils from '../generated-artifacts/DevUtils.json';
|
||||
import * as LibAssetData from '../generated-artifacts/LibAssetData.json';
|
||||
import * as LibDydxBalance from '../generated-artifacts/LibDydxBalance.json';
|
||||
import * as LibOrderTransferSimulation from '../generated-artifacts/LibOrderTransferSimulation.json';
|
||||
import * as LibTransactionDecoder from '../generated-artifacts/LibTransactionDecoder.json';
|
||||
export const artifacts = {
|
||||
DevUtils: DevUtils as ContractArtifact,
|
||||
LibAssetData: LibAssetData as ContractArtifact,
|
||||
LibDydxBalance: LibDydxBalance as ContractArtifact,
|
||||
LibOrderTransferSimulation: LibOrderTransferSimulation as ContractArtifact,
|
||||
LibTransactionDecoder: LibTransactionDecoder as ContractArtifact,
|
||||
};
|
||||
|
@@ -5,5 +5,6 @@
|
||||
*/
|
||||
export * from '../generated-wrappers/dev_utils';
|
||||
export * from '../generated-wrappers/lib_asset_data';
|
||||
export * from '../generated-wrappers/lib_dydx_balance';
|
||||
export * from '../generated-wrappers/lib_order_transfer_simulation';
|
||||
export * from '../generated-wrappers/lib_transaction_decoder';
|
||||
|
@@ -11,10 +11,13 @@ import * as DevUtils from '../test/generated-artifacts/DevUtils.json';
|
||||
import * as EthBalanceChecker from '../test/generated-artifacts/EthBalanceChecker.json';
|
||||
import * as ExternalFunctions from '../test/generated-artifacts/ExternalFunctions.json';
|
||||
import * as LibAssetData from '../test/generated-artifacts/LibAssetData.json';
|
||||
import * as LibDydxBalance from '../test/generated-artifacts/LibDydxBalance.json';
|
||||
import * as LibOrderTransferSimulation from '../test/generated-artifacts/LibOrderTransferSimulation.json';
|
||||
import * as LibTransactionDecoder from '../test/generated-artifacts/LibTransactionDecoder.json';
|
||||
import * as OrderTransferSimulationUtils from '../test/generated-artifacts/OrderTransferSimulationUtils.json';
|
||||
import * as OrderValidationUtils from '../test/generated-artifacts/OrderValidationUtils.json';
|
||||
import * as TestDydx from '../test/generated-artifacts/TestDydx.json';
|
||||
import * as TestLibDydxBalance from '../test/generated-artifacts/TestLibDydxBalance.json';
|
||||
export const artifacts = {
|
||||
Addresses: Addresses as ContractArtifact,
|
||||
AssetBalance: AssetBalance as ContractArtifact,
|
||||
@@ -22,8 +25,11 @@ export const artifacts = {
|
||||
EthBalanceChecker: EthBalanceChecker as ContractArtifact,
|
||||
ExternalFunctions: ExternalFunctions as ContractArtifact,
|
||||
LibAssetData: LibAssetData as ContractArtifact,
|
||||
LibDydxBalance: LibDydxBalance as ContractArtifact,
|
||||
LibOrderTransferSimulation: LibOrderTransferSimulation as ContractArtifact,
|
||||
LibTransactionDecoder: LibTransactionDecoder as ContractArtifact,
|
||||
OrderTransferSimulationUtils: OrderTransferSimulationUtils as ContractArtifact,
|
||||
OrderValidationUtils: OrderValidationUtils as ContractArtifact,
|
||||
TestDydx: TestDydx as ContractArtifact,
|
||||
TestLibDydxBalance: TestLibDydxBalance as ContractArtifact,
|
||||
};
|
||||
|
1170
contracts/dev-utils/test/lib_dydx_balance_test.ts
Normal file
1170
contracts/dev-utils/test/lib_dydx_balance_test.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,10 @@ export * from '../test/generated-wrappers/dev_utils';
|
||||
export * from '../test/generated-wrappers/eth_balance_checker';
|
||||
export * from '../test/generated-wrappers/external_functions';
|
||||
export * from '../test/generated-wrappers/lib_asset_data';
|
||||
export * from '../test/generated-wrappers/lib_dydx_balance';
|
||||
export * from '../test/generated-wrappers/lib_order_transfer_simulation';
|
||||
export * from '../test/generated-wrappers/lib_transaction_decoder';
|
||||
export * from '../test/generated-wrappers/order_transfer_simulation_utils';
|
||||
export * from '../test/generated-wrappers/order_validation_utils';
|
||||
export * from '../test/generated-wrappers/test_dydx';
|
||||
export * from '../test/generated-wrappers/test_lib_dydx_balance';
|
||||
|
@@ -5,6 +5,7 @@
|
||||
"files": [
|
||||
"generated-artifacts/DevUtils.json",
|
||||
"generated-artifacts/LibAssetData.json",
|
||||
"generated-artifacts/LibDydxBalance.json",
|
||||
"generated-artifacts/LibOrderTransferSimulation.json",
|
||||
"generated-artifacts/LibTransactionDecoder.json",
|
||||
"test/generated-artifacts/Addresses.json",
|
||||
@@ -13,10 +14,13 @@
|
||||
"test/generated-artifacts/EthBalanceChecker.json",
|
||||
"test/generated-artifacts/ExternalFunctions.json",
|
||||
"test/generated-artifacts/LibAssetData.json",
|
||||
"test/generated-artifacts/LibDydxBalance.json",
|
||||
"test/generated-artifacts/LibOrderTransferSimulation.json",
|
||||
"test/generated-artifacts/LibTransactionDecoder.json",
|
||||
"test/generated-artifacts/OrderTransferSimulationUtils.json",
|
||||
"test/generated-artifacts/OrderValidationUtils.json"
|
||||
"test/generated-artifacts/OrderValidationUtils.json",
|
||||
"test/generated-artifacts/TestDydx.json",
|
||||
"test/generated-artifacts/TestLibDydxBalance.json"
|
||||
],
|
||||
"exclude": ["./deploy/solc/solc_bin"]
|
||||
}
|
||||
|
@@ -1,4 +1,31 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "2.1.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "2.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1581748629,
|
||||
"version": "2.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.1.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.1.3 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.2 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.1 - _February 15, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.0 - _February 8, 2020_
|
||||
|
||||
* Fix broken tests (#2462)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc1155",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,11 +52,11 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/types": "^3.1.2",
|
||||
@@ -80,10 +80,10 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/base-contract": "^6.2.1",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,10 +1,42 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "1.4.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "1.4.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.4.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Added Curve contract sampling",
|
||||
"pr": 2483
|
||||
}
|
||||
],
|
||||
"timestamp": 1581748629
|
||||
},
|
||||
{
|
||||
"version": "1.3.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Catch reverts to `DevUtils` calls",
|
||||
"pr": 2476
|
||||
},
|
||||
{
|
||||
"note": "Remove wrapper functions and introduce `batchCall()`",
|
||||
"pr": 2477
|
||||
}
|
||||
],
|
||||
"timestamp": 1581204851
|
||||
|
@@ -5,9 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.4.2 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.4.1 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.4.0 - _February 15, 2020_
|
||||
|
||||
* Added Curve contract sampling (#2483)
|
||||
|
||||
## v1.3.0 - _February 8, 2020_
|
||||
|
||||
* Catch reverts to `DevUtils` calls (#2476)
|
||||
* Remove wrapper functions and introduce `batchCall()` (#2477)
|
||||
|
||||
## v1.2.1 - _February 6, 2020_
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -21,7 +21,6 @@ pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IUniswapExchangeFactory.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
@@ -30,160 +29,46 @@ import "./IERC20BridgeSampler.sol";
|
||||
import "./IEth2Dai.sol";
|
||||
import "./IKyberNetwork.sol";
|
||||
import "./IUniswapExchangeQuotes.sol";
|
||||
import "./ICurve.sol";
|
||||
|
||||
|
||||
contract ERC20BridgeSampler is
|
||||
IERC20BridgeSampler,
|
||||
DeploymentConstants
|
||||
{
|
||||
bytes4 constant internal ERC20_PROXY_ID = 0xf47261b0; // bytes4(keccak256("ERC20Token(address)"));
|
||||
uint256 constant internal KYBER_SAMPLE_CALL_GAS = 1500e3;
|
||||
uint256 constant internal UNISWAP_SAMPLE_CALL_GAS = 150e3;
|
||||
uint256 constant internal ETH2DAI_SAMPLE_CALL_GAS = 1000e3;
|
||||
uint256 constant internal DEV_UTILS_CALL_GAS = 500e3;
|
||||
address constant private UNISWAP_SOURCE = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
|
||||
address constant private ETH2DAI_SOURCE = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;
|
||||
address constant private KYBER_SOURCE = 0x818E6FECD516Ecc3849DAf6845e3EC868087B755;
|
||||
/// @dev Gas limit for DevUtils calls.
|
||||
uint256 constant internal DEV_UTILS_CALL_GAS = 500e3; // 500k
|
||||
/// @dev Gas limit for Kyber calls.
|
||||
uint256 constant internal KYBER_CALL_GAS = 1500e3; // 1.5m
|
||||
/// @dev Gas limit for Uniswap calls.
|
||||
uint256 constant internal UNISWAP_CALL_GAS = 150e3; // 150k
|
||||
/// @dev Base gas limit for Eth2Dai calls.
|
||||
uint256 constant internal ETH2DAI_CALL_GAS = 1000e3; // 1m
|
||||
/// @dev Base gas limit for Curve calls. Some Curves have multiple tokens
|
||||
/// So a reasonable ceil is 150k per token. Biggest Curve has 4 tokens.
|
||||
uint256 constant internal CURVE_CALL_GAS = 600e3; // 600k
|
||||
|
||||
/// @dev Query batches of native orders and sample sell quotes on multiple DEXes at once.
|
||||
/// @param orders Batches of Native orders to query.
|
||||
/// @param orderSignatures Batches of Signatures for each respective order in `orders`.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @param takerTokenAmounts Batches of Taker token sell amount for each sample.
|
||||
/// @return ordersAndSamples How much taker asset can be filled
|
||||
/// by each order in `orders`. Maker amounts bought for each source at
|
||||
/// each taker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryBatchOrdersAndSampleSells(
|
||||
LibOrder.Order[][] memory orders,
|
||||
bytes[][] memory orderSignatures,
|
||||
address[] memory sources,
|
||||
uint256[][] memory takerTokenAmounts
|
||||
)
|
||||
public
|
||||
/// @dev Call multiple public functions on this contract in a single transaction.
|
||||
/// @param callDatas ABI-encoded call data for each function call.
|
||||
/// @return callResults ABI-encoded results data for each call.
|
||||
function batchCall(bytes[] calldata callDatas)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
OrdersAndSample[] memory ordersAndSamples
|
||||
)
|
||||
returns (bytes[] memory callResults)
|
||||
{
|
||||
ordersAndSamples = new OrdersAndSample[](orders.length);
|
||||
for (uint256 i = 0; i != orders.length; i++) {
|
||||
(
|
||||
uint256[] memory orderFillableAssetAmounts,
|
||||
uint256[][] memory tokenAmountsBySource
|
||||
) = queryOrdersAndSampleSells(orders[i], orderSignatures[i], sources, takerTokenAmounts[i]);
|
||||
ordersAndSamples[i].orderFillableAssetAmounts = orderFillableAssetAmounts;
|
||||
ordersAndSamples[i].tokenAmountsBySource = tokenAmountsBySource;
|
||||
callResults = new bytes[](callDatas.length);
|
||||
for (uint256 i = 0; i != callDatas.length; ++i) {
|
||||
(bool didSucceed, bytes memory resultData) = address(this).staticcall(callDatas[i]);
|
||||
if (!didSucceed) {
|
||||
assembly { revert(add(resultData, 0x20), mload(resultData)) }
|
||||
}
|
||||
callResults[i] = resultData;
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Query batches of native orders and sample buy quotes on multiple DEXes at once.
|
||||
/// @param orders Batches of Native orders to query.
|
||||
/// @param orderSignatures Batches of Signatures for each respective order in `orders`.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @param makerTokenAmounts Batches of Maker token sell amount for each sample.
|
||||
/// @return ordersAndSamples How much taker asset can be filled
|
||||
/// by each order in `orders`. Taker amounts sold for each source at
|
||||
/// each maker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryBatchOrdersAndSampleBuys(
|
||||
LibOrder.Order[][] memory orders,
|
||||
bytes[][] memory orderSignatures,
|
||||
address[] memory sources,
|
||||
uint256[][] memory makerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (
|
||||
OrdersAndSample[] memory ordersAndSamples
|
||||
)
|
||||
{
|
||||
ordersAndSamples = new OrdersAndSample[](orders.length);
|
||||
for (uint256 i = 0; i != orders.length; i++) {
|
||||
(
|
||||
uint256[] memory orderFillableAssetAmounts,
|
||||
uint256[][] memory tokenAmountsBySource
|
||||
) = queryOrdersAndSampleBuys(orders[i], orderSignatures[i], sources, makerTokenAmounts[i]);
|
||||
ordersAndSamples[i].orderFillableAssetAmounts = orderFillableAssetAmounts;
|
||||
ordersAndSamples[i].tokenAmountsBySource = tokenAmountsBySource;
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Query native orders and sample sell quotes on multiple DEXes at once.
|
||||
/// @param orders Native orders to query.
|
||||
/// @param orderSignatures Signatures for each respective order in `orders`.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return orderFillableTakerAssetAmounts How much taker asset can be filled
|
||||
/// by each order in `orders`.
|
||||
/// @return makerTokenAmountsBySource Maker amounts bought for each source at
|
||||
/// each taker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryOrdersAndSampleSells(
|
||||
LibOrder.Order[] memory orders,
|
||||
bytes[] memory orderSignatures,
|
||||
address[] memory sources,
|
||||
uint256[] memory takerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (
|
||||
uint256[] memory orderFillableTakerAssetAmounts,
|
||||
uint256[][] memory makerTokenAmountsBySource
|
||||
)
|
||||
{
|
||||
require(orders.length != 0, "ERC20BridgeSampler/EMPTY_ORDERS");
|
||||
orderFillableTakerAssetAmounts = getOrderFillableTakerAssetAmounts(
|
||||
orders,
|
||||
orderSignatures
|
||||
);
|
||||
makerTokenAmountsBySource = sampleSells(
|
||||
sources,
|
||||
_assetDataToTokenAddress(orders[0].takerAssetData),
|
||||
_assetDataToTokenAddress(orders[0].makerAssetData),
|
||||
takerTokenAmounts
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Query native orders and sample buy quotes on multiple DEXes at once.
|
||||
/// @param orders Native orders to query.
|
||||
/// @param orderSignatures Signatures for each respective order in `orders`.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @param makerTokenAmounts Maker token buy amount for each sample.
|
||||
/// @return orderFillableMakerAssetAmounts How much maker asset can be filled
|
||||
/// by each order in `orders`.
|
||||
/// @return takerTokenAmountsBySource Taker amounts sold for each source at
|
||||
/// each maker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryOrdersAndSampleBuys(
|
||||
LibOrder.Order[] memory orders,
|
||||
bytes[] memory orderSignatures,
|
||||
address[] memory sources,
|
||||
uint256[] memory makerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (
|
||||
uint256[] memory orderFillableMakerAssetAmounts,
|
||||
uint256[][] memory makerTokenAmountsBySource
|
||||
)
|
||||
{
|
||||
require(orders.length != 0, "ERC20BridgeSampler/EMPTY_ORDERS");
|
||||
orderFillableMakerAssetAmounts = getOrderFillableMakerAssetAmounts(
|
||||
orders,
|
||||
orderSignatures
|
||||
);
|
||||
makerTokenAmountsBySource = sampleBuys(
|
||||
sources,
|
||||
_assetDataToTokenAddress(orders[0].takerAssetData),
|
||||
_assetDataToTokenAddress(orders[0].makerAssetData),
|
||||
makerTokenAmounts
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Queries the fillable taker asset amounts of native orders.
|
||||
/// Effectively ignores orders that have empty signatures or
|
||||
/// maker/taker asset amounts (returning 0).
|
||||
/// maker/taker asset amounts (returning 0).
|
||||
/// @param orders Native orders to query.
|
||||
/// @param orderSignatures Signatures for each respective order in `orders`.
|
||||
/// @return orderFillableTakerAssetAmounts How much taker asset can be filled
|
||||
@@ -270,66 +155,6 @@ contract ERC20BridgeSampler is
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Sample sell quotes on multiple DEXes at once.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return makerTokenAmountsBySource Maker amounts bought for each source at
|
||||
/// each taker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function sampleSells(
|
||||
address[] memory sources,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] memory takerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (uint256[][] memory makerTokenAmountsBySource)
|
||||
{
|
||||
uint256 numSources = sources.length;
|
||||
makerTokenAmountsBySource = new uint256[][](numSources);
|
||||
for (uint256 i = 0; i < numSources; i++) {
|
||||
makerTokenAmountsBySource[i] = _sampleSellSource(
|
||||
sources[i],
|
||||
takerToken,
|
||||
makerToken,
|
||||
takerTokenAmounts
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Query native orders and sample buy quotes on multiple DEXes at once.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param makerTokenAmounts Maker token buy amount for each sample.
|
||||
/// @return takerTokenAmountsBySource Taker amounts sold for each source at
|
||||
/// each maker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function sampleBuys(
|
||||
address[] memory sources,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] memory makerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (uint256[][] memory takerTokenAmountsBySource)
|
||||
{
|
||||
uint256 numSources = sources.length;
|
||||
takerTokenAmountsBySource = new uint256[][](numSources);
|
||||
for (uint256 i = 0; i < numSources; i++) {
|
||||
takerTokenAmountsBySource[i] = _sampleBuySource(
|
||||
sources[i],
|
||||
takerToken,
|
||||
makerToken,
|
||||
makerTokenAmounts
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Sample sell quotes from Kyber.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
@@ -354,7 +179,7 @@ contract ERC20BridgeSampler is
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
_getKyberNetworkProxyAddress().staticcall.gas(KYBER_SAMPLE_CALL_GAS)(
|
||||
_getKyberNetworkProxyAddress().staticcall.gas(KYBER_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IKyberNetwork(0).getExpectedRate.selector,
|
||||
_takerToken,
|
||||
@@ -396,7 +221,7 @@ contract ERC20BridgeSampler is
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
_getEth2DaiAddress().staticcall.gas(ETH2DAI_SAMPLE_CALL_GAS)(
|
||||
_getEth2DaiAddress().staticcall.gas(ETH2DAI_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IEth2Dai(0).getBuyAmount.selector,
|
||||
makerToken,
|
||||
@@ -433,7 +258,7 @@ contract ERC20BridgeSampler is
|
||||
takerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
_getEth2DaiAddress().staticcall.gas(ETH2DAI_SAMPLE_CALL_GAS)(
|
||||
_getEth2DaiAddress().staticcall.gas(ETH2DAI_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IEth2Dai(0).getPayAmount.selector,
|
||||
takerToken,
|
||||
@@ -568,6 +393,44 @@ contract ERC20BridgeSampler is
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Sample sell quotes from Curve.
|
||||
/// @param curveAddress Address of the Curve contract.
|
||||
/// @param fromTokenIdx Index of the taker token (what to sell).
|
||||
/// @param toTokenIdx Index of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||
/// amount.
|
||||
function sampleSellsFromCurve(
|
||||
address curveAddress,
|
||||
int128 fromTokenIdx,
|
||||
int128 toTokenIdx,
|
||||
uint256[] memory takerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (uint256[] memory makerTokenAmounts)
|
||||
{
|
||||
uint256 numSamples = takerTokenAmounts.length;
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
curveAddress.staticcall.gas(CURVE_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
ICurve(0).get_dy_underlying.selector,
|
||||
fromTokenIdx,
|
||||
toTokenIdx,
|
||||
takerTokenAmounts[i]
|
||||
));
|
||||
uint256 buyAmount = 0;
|
||||
if (didSucceed) {
|
||||
buyAmount = abi.decode(resultData, (uint256));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
makerTokenAmounts[i] = buyAmount;
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Overridable way to get token decimals.
|
||||
/// @param tokenAddress Address of the token.
|
||||
/// @return decimals The decimal places for the token.
|
||||
@@ -599,7 +462,7 @@ contract ERC20BridgeSampler is
|
||||
}
|
||||
bytes memory resultData;
|
||||
(didSucceed, resultData) =
|
||||
uniswapExchangeAddress.staticcall.gas(UNISWAP_SAMPLE_CALL_GAS)(
|
||||
uniswapExchangeAddress.staticcall.gas(UNISWAP_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
functionSelector,
|
||||
inputAmount
|
||||
@@ -609,59 +472,6 @@ contract ERC20BridgeSampler is
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Samples a supported sell source, defined by its address.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||
/// amount.
|
||||
function _sampleSellSource(
|
||||
address source,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] memory takerTokenAmounts
|
||||
)
|
||||
private
|
||||
view
|
||||
returns (uint256[] memory makerTokenAmounts)
|
||||
{
|
||||
if (source == ETH2DAI_SOURCE) {
|
||||
return sampleSellsFromEth2Dai(takerToken, makerToken, takerTokenAmounts);
|
||||
}
|
||||
if (source == UNISWAP_SOURCE) {
|
||||
return sampleSellsFromUniswap(takerToken, makerToken, takerTokenAmounts);
|
||||
}
|
||||
if (source == KYBER_SOURCE) {
|
||||
return sampleSellsFromKyberNetwork(takerToken, makerToken, takerTokenAmounts);
|
||||
}
|
||||
revert("ERC20BridgeSampler/UNSUPPORTED_SOURCE");
|
||||
}
|
||||
|
||||
/// @dev Samples a supported buy source, defined by its address.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param makerTokenAmounts Maker token sell amount for each sample.
|
||||
/// @return takerTokenAmounts Taker amounts sold at each maker token
|
||||
/// amount.
|
||||
function _sampleBuySource(
|
||||
address source,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] memory makerTokenAmounts
|
||||
)
|
||||
private
|
||||
view
|
||||
returns (uint256[] memory takerTokenAmounts)
|
||||
{
|
||||
if (source == ETH2DAI_SOURCE) {
|
||||
return sampleBuysFromEth2Dai(takerToken, makerToken, makerTokenAmounts);
|
||||
}
|
||||
if (source == UNISWAP_SOURCE) {
|
||||
return sampleBuysFromUniswap(takerToken, makerToken, makerTokenAmounts);
|
||||
}
|
||||
revert("ERC20BridgeSampler/UNSUPPORTED_SOURCE");
|
||||
}
|
||||
|
||||
/// @dev Retrive an existing Uniswap exchange contract.
|
||||
/// Throws if the exchange does not exist.
|
||||
/// @param tokenAddress Address of the token contract.
|
||||
@@ -677,23 +487,9 @@ contract ERC20BridgeSampler is
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Extract the token address from ERC20 proxy asset data.
|
||||
/// @param assetData ERC20 asset data.
|
||||
/// @return tokenAddress The decoded token address.
|
||||
function _assetDataToTokenAddress(bytes memory assetData)
|
||||
private
|
||||
pure
|
||||
returns (address tokenAddress)
|
||||
{
|
||||
require(assetData.length == 36, "ERC20BridgeSampler/INVALID_ASSET_DATA");
|
||||
bytes4 selector;
|
||||
assembly {
|
||||
selector := and(mload(add(assetData, 0x20)), 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
|
||||
tokenAddress := mload(add(assetData, 0x24))
|
||||
}
|
||||
require(selector == ERC20_PROXY_ID, "ERC20BridgeSampler/UNSUPPORTED_ASSET_PROXY");
|
||||
}
|
||||
|
||||
/// @dev Assert that the tokens in a trade pair are valid.
|
||||
/// @param makerToken Address of the maker token.
|
||||
/// @param takerToken Address of the taker token.
|
||||
function _assertValidPair(address makerToken, address takerToken)
|
||||
private
|
||||
pure
|
||||
|
87
contracts/erc20-bridge-sampler/contracts/src/ICurve.sol
Normal file
87
contracts/erc20-bridge-sampler/contracts/src/ICurve.sol
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
|
||||
// solhint-disable func-name-mixedcase
|
||||
interface ICurve {
|
||||
|
||||
/// @dev Sell `sellAmount` of `fromToken` token and receive `toToken` token.
|
||||
/// This function exists on early versions of Curve (USDC/DAI)
|
||||
/// @param i The token index being sold.
|
||||
/// @param j The token index being bought.
|
||||
/// @param sellAmount The amount of token being bought.
|
||||
/// @param minBuyAmount The minimum buy amount of the token being bought.
|
||||
/// @param deadline The time in seconds when this operation should expire.
|
||||
function exchange_underlying(
|
||||
int128 i,
|
||||
int128 j,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount,
|
||||
uint256 deadline
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Sell `sellAmount` of `fromToken` token and receive `toToken` token.
|
||||
/// This function exists on later versions of Curve (USDC/DAI/USDT)
|
||||
/// @param i The token index being sold.
|
||||
/// @param j The token index being bought.
|
||||
/// @param sellAmount The amount of token being bought.
|
||||
/// @param minBuyAmount The minimum buy amount of the token being bought.
|
||||
function exchange_underlying(
|
||||
int128 i,
|
||||
int128 j,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Get the amount of `toToken` by selling `sellAmount` of `fromToken`
|
||||
/// @param i The token index being sold.
|
||||
/// @param j The token index being bought.
|
||||
/// @param sellAmount The amount of token being bought.
|
||||
function get_dy_underlying(
|
||||
int128 i,
|
||||
int128 j,
|
||||
uint256 sellAmount
|
||||
)
|
||||
external
|
||||
returns (uint256 dy);
|
||||
|
||||
/// @dev Get the amount of `fromToken` by buying `buyAmount` of `toToken`
|
||||
/// This function exists on later versions of Curve (USDC/DAI/USDT)
|
||||
/// @param i The token index being sold.
|
||||
/// @param j The token index being bought.
|
||||
/// @param buyAmount The amount of token being bought.
|
||||
function get_dx_underlying(
|
||||
int128 i,
|
||||
int128 j,
|
||||
uint256 buyAmount
|
||||
)
|
||||
external
|
||||
returns (uint256 dx);
|
||||
|
||||
/// @dev Get the underlying token address from the token index
|
||||
/// @param i The token index.
|
||||
function underlying_coins(
|
||||
int128 i
|
||||
)
|
||||
external
|
||||
returns (address tokenAddress);
|
||||
}
|
@@ -23,98 +23,14 @@ import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
|
||||
|
||||
interface IERC20BridgeSampler {
|
||||
struct OrdersAndSample {
|
||||
uint256[] orderFillableAssetAmounts;
|
||||
uint256[][] tokenAmountsBySource;
|
||||
}
|
||||
|
||||
/// @dev Query batches of native orders and sample sell quotes on multiple DEXes at once.
|
||||
/// @param orders Batches of Native orders to query.
|
||||
/// @param orderSignatures Batches of Signatures for each respective order in `orders`.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @param takerTokenAmounts Batches of Taker token sell amount for each sample.
|
||||
/// @return ordersAndSamples How much taker asset can be filled
|
||||
/// by each order in `orders`. Maker amounts bought for each source at
|
||||
/// each taker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryBatchOrdersAndSampleSells(
|
||||
LibOrder.Order[][] calldata orders,
|
||||
bytes[][] calldata orderSignatures,
|
||||
address[] calldata sources,
|
||||
uint256[][] calldata takerTokenAmounts
|
||||
)
|
||||
/// @dev Call multiple public functions on this contract in a single transaction.
|
||||
/// @param callDatas ABI-encoded call data for each function call.
|
||||
/// @return callResults ABI-encoded results data for each call.
|
||||
function batchCall(bytes[] calldata callDatas)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
OrdersAndSample[] memory ordersAndSamples
|
||||
);
|
||||
|
||||
/// @dev Query batches of native orders and sample buy quotes on multiple DEXes at once.
|
||||
/// @param orders Batches of Native orders to query.
|
||||
/// @param orderSignatures Batches of Signatures for each respective order in `orders`.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @param makerTokenAmounts Batches of Maker token sell amount for each sample.
|
||||
/// @return ordersAndSamples How much taker asset can be filled
|
||||
/// by each order in `orders`. Taker amounts sold for each source at
|
||||
/// each maker token amount. First indexed by source index, then sample
|
||||
/// index
|
||||
function queryBatchOrdersAndSampleBuys(
|
||||
LibOrder.Order[][] calldata orders,
|
||||
bytes[][] calldata orderSignatures,
|
||||
address[] calldata sources,
|
||||
uint256[][] calldata makerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
OrdersAndSample[] memory ordersAndSamples
|
||||
);
|
||||
|
||||
/// @dev Query native orders and sample sell quotes on multiple DEXes at once.
|
||||
/// @param orders Native orders to query.
|
||||
/// @param orderSignatures Signatures for each respective order in `orders`.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return orderFillableTakerAssetAmounts How much taker asset can be filled
|
||||
/// by each order in `orders`.
|
||||
/// @return makerTokenAmountsBySource Maker amounts bought for each source at
|
||||
/// each taker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryOrdersAndSampleSells(
|
||||
LibOrder.Order[] calldata orders,
|
||||
bytes[] calldata orderSignatures,
|
||||
address[] calldata sources,
|
||||
uint256[] calldata takerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint256[] memory orderFillableTakerAssetAmounts,
|
||||
uint256[][] memory makerTokenAmountsBySource
|
||||
);
|
||||
|
||||
/// @dev Query native orders and sample buy quotes on multiple DEXes at once.
|
||||
/// @param orders Native orders to query.
|
||||
/// @param orderSignatures Signatures for each respective order in `orders`.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @param makerTokenAmounts Maker token buy amount for each sample.
|
||||
/// @return orderFillableMakerAssetAmounts How much maker asset can be filled
|
||||
/// by each order in `orders`.
|
||||
/// @return takerTokenAmountsBySource Taker amounts sold for each source at
|
||||
/// each maker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryOrdersAndSampleBuys(
|
||||
LibOrder.Order[] calldata orders,
|
||||
bytes[] calldata orderSignatures,
|
||||
address[] calldata sources,
|
||||
uint256[] calldata makerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint256[] memory orderFillableMakerAssetAmounts,
|
||||
uint256[][] memory makerTokenAmountsBySource
|
||||
);
|
||||
returns (bytes[] memory callResults);
|
||||
|
||||
/// @dev Queries the fillable taker asset amounts of native orders.
|
||||
/// @param orders Native orders to query.
|
||||
@@ -142,39 +58,95 @@ interface IERC20BridgeSampler {
|
||||
view
|
||||
returns (uint256[] memory orderFillableMakerAssetAmounts);
|
||||
|
||||
/// @dev Sample sell quotes on multiple DEXes at once.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @dev Sample sell quotes from Kyber.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return makerTokenAmountsBySource Maker amounts bought for each source at
|
||||
/// each taker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function sampleSells(
|
||||
address[] calldata sources,
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||
/// amount.
|
||||
function sampleSellsFromKyberNetwork(
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] calldata takerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256[][] memory makerTokenAmountsBySource);
|
||||
returns (uint256[] memory makerTokenAmounts);
|
||||
|
||||
/// @dev Query native orders and sample buy quotes on multiple DEXes at once.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
/// @dev Sample sell quotes from Eth2Dai/Oasis.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param makerTokenAmounts Maker token buy amount for each sample.
|
||||
/// @return takerTokenAmountsBySource Taker amounts sold for each source at
|
||||
/// each maker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function sampleBuys(
|
||||
address[] calldata sources,
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||
/// amount.
|
||||
function sampleSellsFromEth2Dai(
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] calldata takerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory makerTokenAmounts);
|
||||
|
||||
/// @dev Sample sell quotes from Uniswap.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||
/// amount.
|
||||
function sampleSellsFromUniswap(
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] calldata takerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory makerTokenAmounts);
|
||||
|
||||
/// @dev Sample buy quotes from Uniswap.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param makerTokenAmounts Maker token sell amount for each sample.
|
||||
/// @return takerTokenAmounts Taker amounts sold at each maker token
|
||||
/// amount.
|
||||
function sampleBuysFromUniswap(
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] calldata makerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256[][] memory takerTokenAmountsBySource);
|
||||
returns (uint256[] memory takerTokenAmounts);
|
||||
|
||||
/// @dev Sample buy quotes from Eth2Dai/Oasis.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Maker token sell amount for each sample.
|
||||
/// @return takerTokenAmounts Taker amounts sold at each maker token
|
||||
/// amount.
|
||||
function sampleBuysFromEth2Dai(
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] calldata makerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory takerTokenAmounts);
|
||||
|
||||
/// @dev Sample sell quotes from Curve.
|
||||
/// @param curveAddress Address of the Curve contract.
|
||||
/// @param fromTokenIdx Index of the taker token (what to sell).
|
||||
/// @param toTokenIdx Index of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||
/// amount.
|
||||
function sampleSellsFromCurve(
|
||||
address curveAddress,
|
||||
int128 fromTokenIdx,
|
||||
int128 toTokenIdx,
|
||||
uint256[] calldata takerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory makerTokenAmounts);
|
||||
}
|
||||
|
@@ -327,7 +327,6 @@ contract TestERC20BridgeSampler is
|
||||
bytes memory
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (
|
||||
LibOrder.OrderInfo memory orderInfo,
|
||||
uint256 fillableTakerAssetAmount,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc20-bridge-sampler",
|
||||
"version": "1.3.0",
|
||||
"version": "1.4.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -38,7 +38,7 @@
|
||||
"config": {
|
||||
"publicInterfaceContracts": "ERC20BridgeSampler,IERC20BridgeSampler",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||
"abis": "./test/generated-artifacts/@(ERC20BridgeSampler|IDevUtils|IERC20BridgeSampler|IEth2Dai|IKyberNetwork|IUniswapExchangeQuotes|TestERC20BridgeSampler).json"
|
||||
"abis": "./test/generated-artifacts/@(ERC20BridgeSampler|ICurve|IDevUtils|IERC20BridgeSampler|IEth2Dai|IKyberNetwork|IUniswapExchangeQuotes|TestERC20BridgeSampler).json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -50,18 +50,18 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-asset-proxy": "^3.2.0",
|
||||
"@0x/contracts-erc20": "^3.1.0",
|
||||
"@0x/contracts-exchange": "^3.2.0",
|
||||
"@0x/contracts-exchange-libs": "^4.3.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-asset-proxy": "^3.2.3",
|
||||
"@0x/contracts-erc20": "^3.1.3",
|
||||
"@0x/contracts-exchange": "^3.2.3",
|
||||
"@0x/contracts-exchange-libs": "^4.3.3",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "*",
|
||||
@@ -79,10 +79,10 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0",
|
||||
"@0x/base-contract": "^6.2.1",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"ethereum-types": "^3.1.0",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
|
@@ -6,6 +6,7 @@
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as ERC20BridgeSampler from '../test/generated-artifacts/ERC20BridgeSampler.json';
|
||||
import * as ICurve from '../test/generated-artifacts/ICurve.json';
|
||||
import * as IDevUtils from '../test/generated-artifacts/IDevUtils.json';
|
||||
import * as IERC20BridgeSampler from '../test/generated-artifacts/IERC20BridgeSampler.json';
|
||||
import * as IEth2Dai from '../test/generated-artifacts/IEth2Dai.json';
|
||||
@@ -14,6 +15,7 @@ import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExc
|
||||
import * as TestERC20BridgeSampler from '../test/generated-artifacts/TestERC20BridgeSampler.json';
|
||||
export const artifacts = {
|
||||
ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact,
|
||||
ICurve: ICurve as ContractArtifact,
|
||||
IDevUtils: IDevUtils as ContractArtifact,
|
||||
IERC20BridgeSampler: IERC20BridgeSampler as ContractArtifact,
|
||||
IEth2Dai: IEth2Dai as ContractArtifact,
|
||||
|
@@ -25,19 +25,6 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
const ETH2DAI_SALT = '0xb713b61bb9bb2958a0f5d1534b21e94fc68c4c0c034b0902ed844f2f6cd1b4f7';
|
||||
const UNISWAP_BASE_SALT = '0x1d6a6a0506b0b4a554b907a4c29d9f4674e461989d9c1921feb17b26716385ab';
|
||||
const ERC20_PROXY_ID = '0xf47261b0';
|
||||
const INVALID_ASSET_PROXY_ASSET_DATA = hexUtils.concat('0xf47261b1', hexUtils.leftPad(randomAddress()));
|
||||
const INVALID_ASSET_DATA = hexUtils.random(37);
|
||||
const SELL_SOURCES = ['Eth2Dai', 'Kyber', 'Uniswap'];
|
||||
const BUY_SOURCES = ['Eth2Dai', 'Uniswap'];
|
||||
const SOURCE_IDS: { [source: string]: string } = {
|
||||
Uniswap: '0xc0a47dfe034b400b47bdad5fecda2621de6c4d95',
|
||||
Eth2Dai: '0x39755357759ce0d7f32dc8dc45414cca409ae24e',
|
||||
Kyber: '0x818e6fecd516ecc3849daf6845e3ec868087b755',
|
||||
};
|
||||
const EMPTY_ORDERS_ERROR = 'ERC20BridgeSampler/EMPTY_ORDERS';
|
||||
const UNSUPPORTED_ASSET_PROXY_ERROR = 'ERC20BridgeSampler/UNSUPPORTED_ASSET_PROXY';
|
||||
const INVALID_ASSET_DATA_ERROR = 'ERC20BridgeSampler/INVALID_ASSET_DATA';
|
||||
const UNSUPPORTED_SOURCE_ERROR = 'ERC20BridgeSampler/UNSUPPORTED_SOURCE';
|
||||
const INVALID_TOKEN_PAIR_ERROR = 'ERC20BridgeSampler/INVALID_TOKEN_PAIR';
|
||||
const MAKER_TOKEN = randomAddress();
|
||||
const TAKER_TOKEN = randomAddress();
|
||||
@@ -190,7 +177,7 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
}
|
||||
|
||||
function getDeterministicFillableTakerAssetAmount(order: Order): BigNumber {
|
||||
const hash = getPackedHash(hexUtils.toHex(order.salt, 32));
|
||||
const hash = getPackedHash(hexUtils.leftPad(order.salt));
|
||||
const orderStatus = new BigNumber(hash).mod(100).toNumber() > 90 ? 5 : 3;
|
||||
const isValidSignature = !!new BigNumber(hash).mod(2).toNumber();
|
||||
if (orderStatus !== 3 || !isValidSignature) {
|
||||
@@ -324,329 +311,6 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('queryOrdersAndSampleSells()', () => {
|
||||
const ORDERS = createOrders(MAKER_TOKEN, TAKER_TOKEN);
|
||||
const SIGNATURES: string[] = _.times(ORDERS.length, i => hexUtils.random());
|
||||
|
||||
before(async () => {
|
||||
await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync();
|
||||
});
|
||||
|
||||
it('returns expected fillable amounts for each order', async () => {
|
||||
const takerTokenAmounts = getSampleAmounts(TAKER_TOKEN);
|
||||
const expectedFillableAmounts = ORDERS.map(getDeterministicFillableTakerAssetAmount);
|
||||
const [orderInfos] = await testContract
|
||||
.queryOrdersAndSampleSells(ORDERS, SIGNATURES, SELL_SOURCES.map(n => SOURCE_IDS[n]), takerTokenAmounts)
|
||||
.callAsync();
|
||||
expect(orderInfos).to.deep.eq(expectedFillableAmounts);
|
||||
});
|
||||
|
||||
it('can return quotes for all sources', async () => {
|
||||
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
|
||||
const expectedQuotes = getDeterministicSellQuotes(TAKER_TOKEN, MAKER_TOKEN, SELL_SOURCES, sampleAmounts);
|
||||
const [, quotes] = await testContract
|
||||
.queryOrdersAndSampleSells(ORDERS, SIGNATURES, SELL_SOURCES.map(n => SOURCE_IDS[n]), sampleAmounts)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
|
||||
it('throws if no orders are passed in', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleSells([], [], SELL_SOURCES.map(n => SOURCE_IDS[n]), getSampleAmounts(TAKER_TOKEN))
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(EMPTY_ORDERS_ERROR);
|
||||
});
|
||||
|
||||
it('throws with an unsupported source', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleSells(
|
||||
ORDERS,
|
||||
SIGNATURES,
|
||||
[...SELL_SOURCES.map(n => SOURCE_IDS[n]), randomAddress()],
|
||||
getSampleAmounts(TAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(UNSUPPORTED_SOURCE_ERROR);
|
||||
});
|
||||
|
||||
it('throws with non-ERC20 maker asset data', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleSells(
|
||||
ORDERS.map(o => ({
|
||||
...o,
|
||||
makerAssetData: INVALID_ASSET_PROXY_ASSET_DATA,
|
||||
})),
|
||||
SIGNATURES,
|
||||
SELL_SOURCES.map(n => SOURCE_IDS[n]),
|
||||
getSampleAmounts(TAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(UNSUPPORTED_ASSET_PROXY_ERROR);
|
||||
});
|
||||
|
||||
it('throws with non-ERC20 taker asset data', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleSells(
|
||||
ORDERS.map(o => ({
|
||||
...o,
|
||||
takerAssetData: INVALID_ASSET_PROXY_ASSET_DATA,
|
||||
})),
|
||||
SIGNATURES,
|
||||
SELL_SOURCES.map(n => SOURCE_IDS[n]),
|
||||
getSampleAmounts(TAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(UNSUPPORTED_ASSET_PROXY_ERROR);
|
||||
});
|
||||
|
||||
it('throws with invalid maker asset data', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleSells(
|
||||
ORDERS.map(o => ({
|
||||
...o,
|
||||
makerAssetData: INVALID_ASSET_DATA,
|
||||
})),
|
||||
SIGNATURES,
|
||||
SELL_SOURCES.map(n => SOURCE_IDS[n]),
|
||||
getSampleAmounts(TAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(INVALID_ASSET_DATA_ERROR);
|
||||
});
|
||||
|
||||
it('throws with invalid taker asset data', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleSells(
|
||||
ORDERS.map(o => ({
|
||||
...o,
|
||||
takerAssetData: INVALID_ASSET_DATA,
|
||||
})),
|
||||
SIGNATURES,
|
||||
SELL_SOURCES.map(n => SOURCE_IDS[n]),
|
||||
getSampleAmounts(TAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(INVALID_ASSET_DATA_ERROR);
|
||||
});
|
||||
});
|
||||
|
||||
describe('queryOrdersAndSampleBuys()', () => {
|
||||
const ORDERS = createOrders(MAKER_TOKEN, TAKER_TOKEN);
|
||||
const SIGNATURES: string[] = _.times(ORDERS.length, i => hexUtils.random());
|
||||
|
||||
before(async () => {
|
||||
await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync();
|
||||
});
|
||||
|
||||
it('returns expected fillable amounts for each order', async () => {
|
||||
const takerTokenAmounts = getSampleAmounts(MAKER_TOKEN);
|
||||
const expectedFillableAmounts = ORDERS.map(getDeterministicFillableMakerAssetAmount);
|
||||
const [orderInfos] = await testContract
|
||||
.queryOrdersAndSampleBuys(ORDERS, SIGNATURES, BUY_SOURCES.map(n => SOURCE_IDS[n]), takerTokenAmounts)
|
||||
.callAsync();
|
||||
expect(orderInfos).to.deep.eq(expectedFillableAmounts);
|
||||
});
|
||||
|
||||
it('can return quotes for all sources', async () => {
|
||||
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
|
||||
const expectedQuotes = getDeterministicBuyQuotes(TAKER_TOKEN, MAKER_TOKEN, BUY_SOURCES, sampleAmounts);
|
||||
const [, quotes] = await testContract
|
||||
.queryOrdersAndSampleBuys(ORDERS, SIGNATURES, BUY_SOURCES.map(n => SOURCE_IDS[n]), sampleAmounts)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
|
||||
it('throws if no orders are passed in', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleBuys([], [], BUY_SOURCES.map(n => SOURCE_IDS[n]), getSampleAmounts(MAKER_TOKEN))
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(EMPTY_ORDERS_ERROR);
|
||||
});
|
||||
|
||||
it('throws with an unsupported source', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleBuys(
|
||||
ORDERS,
|
||||
SIGNATURES,
|
||||
[...BUY_SOURCES.map(n => SOURCE_IDS[n]), randomAddress()],
|
||||
getSampleAmounts(MAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(UNSUPPORTED_SOURCE_ERROR);
|
||||
});
|
||||
|
||||
it('throws if kyber is passed in as a source', async () => {
|
||||
const sources = [...BUY_SOURCES, 'Kyber'];
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleBuys(
|
||||
ORDERS,
|
||||
SIGNATURES,
|
||||
sources.map(n => SOURCE_IDS[n]),
|
||||
getSampleAmounts(MAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(UNSUPPORTED_SOURCE_ERROR);
|
||||
});
|
||||
|
||||
it('throws with non-ERC20 maker asset data', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleBuys(
|
||||
ORDERS.map(o => ({
|
||||
...o,
|
||||
makerAssetData: INVALID_ASSET_PROXY_ASSET_DATA,
|
||||
})),
|
||||
SIGNATURES,
|
||||
BUY_SOURCES.map(n => SOURCE_IDS[n]),
|
||||
getSampleAmounts(MAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(UNSUPPORTED_ASSET_PROXY_ERROR);
|
||||
});
|
||||
|
||||
it('throws with non-ERC20 taker asset data', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleBuys(
|
||||
ORDERS.map(o => ({
|
||||
...o,
|
||||
takerAssetData: INVALID_ASSET_PROXY_ASSET_DATA,
|
||||
})),
|
||||
SIGNATURES,
|
||||
BUY_SOURCES.map(n => SOURCE_IDS[n]),
|
||||
getSampleAmounts(MAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(UNSUPPORTED_ASSET_PROXY_ERROR);
|
||||
});
|
||||
|
||||
it('throws with invalid maker asset data', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleBuys(
|
||||
ORDERS.map(o => ({
|
||||
...o,
|
||||
makerAssetData: INVALID_ASSET_DATA,
|
||||
})),
|
||||
SIGNATURES,
|
||||
BUY_SOURCES.map(n => SOURCE_IDS[n]),
|
||||
getSampleAmounts(MAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(INVALID_ASSET_DATA_ERROR);
|
||||
});
|
||||
|
||||
it('throws with invalid taker asset data', async () => {
|
||||
const tx = testContract
|
||||
.queryOrdersAndSampleBuys(
|
||||
ORDERS.map(o => ({
|
||||
...o,
|
||||
takerAssetData: INVALID_ASSET_DATA,
|
||||
})),
|
||||
SIGNATURES,
|
||||
BUY_SOURCES.map(n => SOURCE_IDS[n]),
|
||||
getSampleAmounts(MAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(INVALID_ASSET_DATA_ERROR);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sampleSells()', () => {
|
||||
before(async () => {
|
||||
await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync();
|
||||
});
|
||||
|
||||
it('returns empty quotes with no sample amounts', async () => {
|
||||
const emptyQuotes = _.times(SELL_SOURCES.length, () => []);
|
||||
const quotes = await testContract
|
||||
.sampleSells(SELL_SOURCES.map(n => SOURCE_IDS[n]), TAKER_TOKEN, MAKER_TOKEN, [])
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(emptyQuotes);
|
||||
});
|
||||
|
||||
it('can return quotes for all sources', async () => {
|
||||
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
|
||||
const expectedQuotes = getDeterministicSellQuotes(TAKER_TOKEN, MAKER_TOKEN, SELL_SOURCES, sampleAmounts);
|
||||
const quotes = await testContract
|
||||
.sampleSells(SELL_SOURCES.map(n => SOURCE_IDS[n]), TAKER_TOKEN, MAKER_TOKEN, sampleAmounts)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
|
||||
it('can return quotes for some sources', async () => {
|
||||
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
|
||||
const sources = _.sampleSize(SELL_SOURCES, 1);
|
||||
const expectedQuotes = getDeterministicSellQuotes(TAKER_TOKEN, MAKER_TOKEN, sources, sampleAmounts);
|
||||
const quotes = await testContract
|
||||
.sampleSells(sources.map(n => SOURCE_IDS[n]), TAKER_TOKEN, MAKER_TOKEN, sampleAmounts)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
|
||||
it('throws with an unsupported source', async () => {
|
||||
const tx = testContract
|
||||
.sampleSells(
|
||||
[...SELL_SOURCES.map(n => SOURCE_IDS[n]), randomAddress()],
|
||||
TAKER_TOKEN,
|
||||
MAKER_TOKEN,
|
||||
getSampleAmounts(TAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(UNSUPPORTED_SOURCE_ERROR);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sampleBuys()', () => {
|
||||
before(async () => {
|
||||
await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync();
|
||||
});
|
||||
|
||||
it('returns empty quotes with no sample amounts', async () => {
|
||||
const emptyQuotes = _.times(BUY_SOURCES.length, () => []);
|
||||
const quotes = await testContract
|
||||
.sampleBuys(BUY_SOURCES.map(n => SOURCE_IDS[n]), TAKER_TOKEN, MAKER_TOKEN, [])
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(emptyQuotes);
|
||||
});
|
||||
|
||||
it('can return quotes for all sources', async () => {
|
||||
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
|
||||
const expectedQuotes = getDeterministicBuyQuotes(TAKER_TOKEN, MAKER_TOKEN, BUY_SOURCES, sampleAmounts);
|
||||
const quotes = await testContract
|
||||
.sampleBuys(BUY_SOURCES.map(n => SOURCE_IDS[n]), TAKER_TOKEN, MAKER_TOKEN, sampleAmounts)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
|
||||
it('can return quotes for some sources', async () => {
|
||||
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
|
||||
const sources = _.sampleSize(BUY_SOURCES, 1);
|
||||
const expectedQuotes = getDeterministicBuyQuotes(TAKER_TOKEN, MAKER_TOKEN, sources, sampleAmounts);
|
||||
const quotes = await testContract
|
||||
.sampleBuys(sources.map(n => SOURCE_IDS[n]), TAKER_TOKEN, MAKER_TOKEN, sampleAmounts)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
|
||||
it('throws with an unsupported source', async () => {
|
||||
const tx = testContract
|
||||
.sampleBuys(
|
||||
[...BUY_SOURCES.map(n => SOURCE_IDS[n]), randomAddress()],
|
||||
TAKER_TOKEN,
|
||||
MAKER_TOKEN,
|
||||
getSampleAmounts(MAKER_TOKEN),
|
||||
)
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(UNSUPPORTED_SOURCE_ERROR);
|
||||
});
|
||||
|
||||
it('throws if kyber is passed in as a source', async () => {
|
||||
const sources = [...BUY_SOURCES, 'Kyber'];
|
||||
const tx = testContract
|
||||
.sampleBuys(sources.map(n => SOURCE_IDS[n]), TAKER_TOKEN, MAKER_TOKEN, getSampleAmounts(MAKER_TOKEN))
|
||||
.callAsync();
|
||||
return expect(tx).to.revertWith(UNSUPPORTED_SOURCE_ERROR);
|
||||
});
|
||||
});
|
||||
|
||||
blockchainTests.resets('sampleSellsFromKyberNetwork()', () => {
|
||||
before(async () => {
|
||||
await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync();
|
||||
@@ -1051,4 +715,65 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
});
|
||||
|
||||
describe('batchCall()', () => {
|
||||
it('can call one function', async () => {
|
||||
const orders = createOrders(MAKER_TOKEN, TAKER_TOKEN);
|
||||
const signatures: string[] = _.times(orders.length, i => hexUtils.random());
|
||||
const expected = orders.map(getDeterministicFillableTakerAssetAmount);
|
||||
const calls = [
|
||||
testContract.getOrderFillableTakerAssetAmounts(orders, signatures).getABIEncodedTransactionData(),
|
||||
];
|
||||
const r = await testContract.batchCall(calls).callAsync();
|
||||
expect(r).to.be.length(1);
|
||||
const actual = testContract.getABIDecodedReturnData<BigNumber[]>('getOrderFillableTakerAssetAmounts', r[0]);
|
||||
expect(actual).to.deep.eq(expected);
|
||||
});
|
||||
|
||||
it('can call two functions', async () => {
|
||||
const numOrders = _.random(1, 10);
|
||||
const orders = _.times(2, () => createOrders(MAKER_TOKEN, TAKER_TOKEN, numOrders));
|
||||
const signatures: string[] = _.times(numOrders, i => hexUtils.random());
|
||||
const expecteds = [
|
||||
orders[0].map(getDeterministicFillableTakerAssetAmount),
|
||||
orders[1].map(getDeterministicFillableMakerAssetAmount),
|
||||
];
|
||||
const calls = [
|
||||
testContract.getOrderFillableTakerAssetAmounts(orders[0], signatures).getABIEncodedTransactionData(),
|
||||
testContract.getOrderFillableMakerAssetAmounts(orders[1], signatures).getABIEncodedTransactionData(),
|
||||
];
|
||||
const r = await testContract.batchCall(calls).callAsync();
|
||||
expect(r).to.be.length(2);
|
||||
expect(testContract.getABIDecodedReturnData('getOrderFillableTakerAssetAmounts', r[0])).to.deep.eq(
|
||||
expecteds[0],
|
||||
);
|
||||
expect(testContract.getABIDecodedReturnData('getOrderFillableMakerAssetAmounts', r[1])).to.deep.eq(
|
||||
expecteds[1],
|
||||
);
|
||||
});
|
||||
|
||||
it('can make recursive calls', async () => {
|
||||
const numOrders = _.random(1, 10);
|
||||
const orders = createOrders(MAKER_TOKEN, TAKER_TOKEN, numOrders);
|
||||
const signatures: string[] = _.times(numOrders, i => hexUtils.random());
|
||||
const expected = orders.map(getDeterministicFillableTakerAssetAmount);
|
||||
let r = await testContract
|
||||
.batchCall([
|
||||
testContract
|
||||
.batchCall([
|
||||
testContract
|
||||
.getOrderFillableTakerAssetAmounts(orders, signatures)
|
||||
.getABIEncodedTransactionData(),
|
||||
])
|
||||
.getABIEncodedTransactionData(),
|
||||
])
|
||||
.callAsync();
|
||||
expect(r).to.be.length(1);
|
||||
r = testContract.getABIDecodedReturnData<string[]>('batchCall', r[0]);
|
||||
expect(r).to.be.length(1);
|
||||
expect(testContract.getABIDecodedReturnData('getOrderFillableTakerAssetAmounts', r[0])).to.deep.eq(
|
||||
expected,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
export * from '../test/generated-wrappers/erc20_bridge_sampler';
|
||||
export * from '../test/generated-wrappers/i_curve';
|
||||
export * from '../test/generated-wrappers/i_dev_utils';
|
||||
export * from '../test/generated-wrappers/i_erc20_bridge_sampler';
|
||||
export * from '../test/generated-wrappers/i_eth2_dai';
|
||||
|
@@ -6,6 +6,7 @@
|
||||
"generated-artifacts/ERC20BridgeSampler.json",
|
||||
"generated-artifacts/IERC20BridgeSampler.json",
|
||||
"test/generated-artifacts/ERC20BridgeSampler.json",
|
||||
"test/generated-artifacts/ICurve.json",
|
||||
"test/generated-artifacts/IDevUtils.json",
|
||||
"test/generated-artifacts/IERC20BridgeSampler.json",
|
||||
"test/generated-artifacts/IEth2Dai.json",
|
||||
|
@@ -1,4 +1,31 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "3.1.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "3.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1581748629,
|
||||
"version": "3.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "3.1.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.3 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.2 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.1 - _February 15, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.0 - _February 8, 2020_
|
||||
|
||||
* Add `allowance()` and `balanceOf()` to `LibERC20Token` (#2464)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc20",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -51,18 +51,18 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "*",
|
||||
@@ -82,7 +82,7 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0"
|
||||
"@0x/base-contract": "^6.2.1"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@@ -1,4 +1,31 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "3.1.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "3.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1581748629,
|
||||
"version": "3.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "3.1.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.3 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.2 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.1 - _February 15, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.0 - _February 8, 2020_
|
||||
|
||||
* Fix broken tests (#2462)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc721",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,18 +52,18 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "*",
|
||||
@@ -84,7 +84,7 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0"
|
||||
"@0x/base-contract": "^6.2.1"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@@ -1,4 +1,31 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "4.2.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "4.2.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1581748629,
|
||||
"version": "4.2.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "4.2.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.2.3 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.2.2 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.2.1 - _February 15, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.2.0 - _February 8, 2020_
|
||||
|
||||
* Export `EvmBytecodeOutputLinkReferences` type. (#2462)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange-forwarder",
|
||||
"version": "4.2.0",
|
||||
"version": "4.2.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,25 +52,25 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-asset-proxy": "^3.2.0",
|
||||
"@0x/contracts-dev-utils": "^1.1.0",
|
||||
"@0x/contracts-erc1155": "^2.1.0",
|
||||
"@0x/contracts-erc20": "^3.1.0",
|
||||
"@0x/contracts-erc721": "^3.1.0",
|
||||
"@0x/contracts-exchange": "^3.2.0",
|
||||
"@0x/contracts-exchange-libs": "^4.3.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/order-utils": "^10.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-asset-proxy": "^3.2.3",
|
||||
"@0x/contracts-dev-utils": "^1.3.1",
|
||||
"@0x/contracts-erc1155": "^2.1.3",
|
||||
"@0x/contracts-erc20": "^3.1.3",
|
||||
"@0x/contracts-erc721": "^3.1.3",
|
||||
"@0x/contracts-exchange": "^3.2.3",
|
||||
"@0x/contracts-exchange-libs": "^4.3.3",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/order-utils": "^10.2.2",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "*",
|
||||
@@ -90,7 +90,7 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0",
|
||||
"@0x/base-contract": "^6.2.1",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"ethereum-types": "^3.1.0"
|
||||
},
|
||||
|
@@ -1,4 +1,31 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "4.3.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "4.3.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1581748629,
|
||||
"version": "4.3.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "4.3.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.3.3 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.3.2 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.3.1 - _February 15, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.3.0 - _February 8, 2020_
|
||||
|
||||
* Export `EvmBytecodeOutputLinkReferences` type. (#2462)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange-libs",
|
||||
"version": "4.3.0",
|
||||
"version": "4.3.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,14 +52,14 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/libs/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/subproviders": "^6.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/subproviders": "^6.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "*",
|
||||
@@ -80,13 +80,13 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/order-utils": "^10.2.0",
|
||||
"@0x/base-contract": "^6.2.1",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/order-utils": "^10.2.2",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"ethereum-types": "^3.1.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,4 +1,31 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "3.2.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "3.2.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1581748629,
|
||||
"version": "3.2.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "3.2.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.2.3 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.2 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.1 - _February 15, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.0 - _February 8, 2020_
|
||||
|
||||
* Flip `LibExchangeRichErrorDecoder` to an actual library. (#2462)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
## Exchange
|
||||
|
||||
This package contains the implementation of the [`Exchange`](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#exchange). This contract is responsible for settling trades and is typically the entry point for all transactions that interact with the 0x protocol. Lightweight examples of how external contracts can interct with the `Exchange` contract can be found in the [examples](./contracts/examples) directory. Addresses of the deployed contracts can be found in this 0x [guide](https://0x.org/docs/guides/0x-cheat-sheet) or the [DEPLOYS](./DEPLOYS.json) file within this package.
|
||||
This package contains the implementation of the [`Exchange`](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#exchange). This contract is responsible for settling trades and is typically the entry point for all transactions that interact with the 0x protocol. Lightweight examples of how external contracts can interact with the `Exchange` contract can be found in the [examples](./contracts/examples) directory. Addresses of the deployed contracts can be found in this 0x [guide](https://0x.org/docs/guides/0x-cheat-sheet) or the [DEPLOYS](./DEPLOYS.json) file within this package.
|
||||
|
||||
## Installation
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange",
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,21 +52,21 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-asset-proxy": "^3.2.0",
|
||||
"@0x/contracts-exchange-libs": "^4.3.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-multisig": "^4.1.0",
|
||||
"@0x/contracts-staking": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-asset-proxy": "^3.2.3",
|
||||
"@0x/contracts-exchange-libs": "^4.3.3",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-multisig": "^4.1.3",
|
||||
"@0x/contracts-staking": "^2.0.10",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "*",
|
||||
@@ -88,13 +88,13 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0",
|
||||
"@0x/contracts-dev-utils": "^1.1.0",
|
||||
"@0x/contracts-erc1155": "^2.1.0",
|
||||
"@0x/contracts-erc20": "^3.1.0",
|
||||
"@0x/contracts-erc721": "^3.1.0",
|
||||
"@0x/order-utils": "^10.2.0",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/base-contract": "^6.2.1",
|
||||
"@0x/contracts-dev-utils": "^1.3.1",
|
||||
"@0x/contracts-erc1155": "^2.1.3",
|
||||
"@0x/contracts-erc20": "^3.1.3",
|
||||
"@0x/contracts-erc721": "^3.1.3",
|
||||
"@0x/order-utils": "^10.2.2",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,4 +1,31 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "6.1.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "6.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1581748629,
|
||||
"version": "6.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "6.1.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v6.1.3 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v6.1.2 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v6.1.1 - _February 15, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v6.1.0 - _February 8, 2020_
|
||||
|
||||
* Export `EvmBytecodeOutputLinkReferences` type. (#2462)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-extensions",
|
||||
"version": "6.1.0",
|
||||
"version": "6.1.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -51,24 +51,24 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contracts-asset-proxy": "^3.2.0",
|
||||
"@0x/contracts-dev-utils": "^1.1.0",
|
||||
"@0x/contracts-erc20": "^3.1.0",
|
||||
"@0x/contracts-erc721": "^3.1.0",
|
||||
"@0x/contracts-exchange": "^3.2.0",
|
||||
"@0x/contracts-exchange-libs": "^4.3.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/order-utils": "^10.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contracts-asset-proxy": "^3.2.3",
|
||||
"@0x/contracts-dev-utils": "^1.3.1",
|
||||
"@0x/contracts-erc20": "^3.1.3",
|
||||
"@0x/contracts-erc721": "^3.1.3",
|
||||
"@0x/contracts-exchange": "^3.2.3",
|
||||
"@0x/contracts-exchange-libs": "^4.3.3",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/order-utils": "^10.2.2",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/ts-doc-gen": "^0.0.22",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "*",
|
||||
@@ -90,7 +90,7 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.0",
|
||||
"@0x/base-contract": "^6.2.1",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"ethereum-types": "^3.1.0"
|
||||
},
|
||||
|
@@ -1,4 +1,44 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1582677073,
|
||||
"version": "2.4.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1582623685,
|
||||
"version": "2.4.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.4.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Added ChainlinkStopLimit contract and tests",
|
||||
"pr": 2473
|
||||
},
|
||||
{
|
||||
"note": "Fixed the mainnet dYdX Bridge tests.",
|
||||
"pr": 2479
|
||||
},
|
||||
{
|
||||
"note": "Addded decoders for stop-limit data",
|
||||
"pr": 2484
|
||||
},
|
||||
{
|
||||
"note": "Added ERC20Sampler and Curve Mainnet test",
|
||||
"pr": 2483
|
||||
}
|
||||
],
|
||||
"timestamp": 1581748629
|
||||
},
|
||||
{
|
||||
"version": "2.3.0",
|
||||
"changes": [
|
||||
@@ -9,6 +49,14 @@
|
||||
{
|
||||
"note": "Update tests for refactored `DevUtils`",
|
||||
"pr": 2464
|
||||
},
|
||||
{
|
||||
"note": "Add DydxBridge validation",
|
||||
"pr": 2466
|
||||
},
|
||||
{
|
||||
"note": "Add DevUtils DydxBridge validation mainnet tests",
|
||||
"pr": 2466
|
||||
}
|
||||
],
|
||||
"timestamp": 1581204851
|
||||
|
@@ -5,10 +5,27 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.4.2 - _February 26, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.4.1 - _February 25, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.4.0 - _February 15, 2020_
|
||||
|
||||
* Added ChainlinkStopLimit contract and tests (#2473)
|
||||
* Fixed the mainnet dYdX Bridge tests. (#2479)
|
||||
* Addded decoders for stop-limit data (#2484)
|
||||
* Added ERC20Sampler and Curve Mainnet test (#2483)
|
||||
|
||||
## v2.3.0 - _February 8, 2020_
|
||||
|
||||
* Remove dependency on `DevUtils` for asset data encoding/decoding (#2462)
|
||||
* Update tests for refactored `DevUtils` (#2464)
|
||||
* Add DydxBridge validation (#2466)
|
||||
* Add DevUtils DydxBridge validation mainnet tests (#2466)
|
||||
|
||||
## v2.2.3 - _February 6, 2020_
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"shouldSaveStandardInput": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "istanbul",
|
||||
"optimizer": {
|
||||
|
50
contracts/integrations/contracts/src/ChainlinkStopLimit.sol
Normal file
50
contracts/integrations/contracts/src/ChainlinkStopLimit.sol
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./interfaces/IChainlinkAggregator.sol";
|
||||
|
||||
|
||||
contract ChainlinkStopLimit {
|
||||
|
||||
/// @dev Checks that the price returned by the encoded Chainlink reference contract is
|
||||
/// within the encoded price range.
|
||||
/// @param stopLimitData Encodes the address of the Chainlink reference contract and the
|
||||
/// valid price range.
|
||||
function checkStopLimit(bytes calldata stopLimitData)
|
||||
external
|
||||
view
|
||||
{
|
||||
(
|
||||
address oracle,
|
||||
int256 minPrice,
|
||||
int256 maxPrice
|
||||
) = abi.decode(
|
||||
stopLimitData,
|
||||
(address, int256, int256)
|
||||
);
|
||||
|
||||
int256 latestPrice = IChainlinkAggregator(oracle).latestAnswer();
|
||||
require(
|
||||
latestPrice >= minPrice && latestPrice <= maxPrice,
|
||||
"ChainlinkStopLimit/OUT_OF_PRICE_RANGE"
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
// A subset of https://github.com/smartcontractkit/chainlink/blob/master/evm/contracts/interfaces/AggregatorInterface.sol
|
||||
interface IChainlinkAggregator {
|
||||
|
||||
/// @dev Returns the latest data value recorded by the contract.
|
||||
/// @return answer The latest data value recorded. For a price oracle aggregator, this will be
|
||||
/// the price of the given asset in USD, multipled by 10^8
|
||||
function latestAnswer() external view returns (int256 answer);
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../src/interfaces/IChainlinkAggregator.sol";
|
||||
|
||||
|
||||
contract TestChainlinkAggregator is
|
||||
IChainlinkAggregator
|
||||
{
|
||||
int256 internal _price;
|
||||
|
||||
function setPrice(int256 price_)
|
||||
external
|
||||
{
|
||||
_price = price_;
|
||||
}
|
||||
|
||||
function latestAnswer()
|
||||
external
|
||||
view
|
||||
returns (int256)
|
||||
{
|
||||
return _price;
|
||||
}
|
||||
}
|
@@ -130,7 +130,7 @@ interface IDydx {
|
||||
/// @dev Deploy this contract and call `init` to run the mainnet DydxBridge integration tests.
|
||||
contract TestDydxUser {
|
||||
|
||||
address public constant DYDX_BRIDGE_ADDRESS = 0x96DdBa19b69D6EA2549f6a12d005595167414744;
|
||||
address public constant DYDX_BRIDGE_ADDRESS = 0x55dC8f21D20D4c6ED3C82916A438A413ca68e335;
|
||||
address public constant DYDX_ADDRESS = 0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e;
|
||||
address public constant DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
|
||||
uint256 public constant DYDX_DAI_MARKET_ID = 3;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-integrations",
|
||||
"version": "2.3.0",
|
||||
"version": "2.4.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -38,7 +38,7 @@
|
||||
},
|
||||
"config": {
|
||||
"publicInterfaceContracts": "TestFramework",
|
||||
"abis": "./test/generated-artifacts/@(TestContractWrapper|TestDydxUser|TestEth2Dai|TestEth2DaiBridge|TestFramework|TestMainnetAggregatorFills|TestSignatureValidationWallet|TestUniswapBridge|TestUniswapExchange|TestUniswapExchangeFactory).json",
|
||||
"abis": "./test/generated-artifacts/@(ChainlinkStopLimit|IChainlinkAggregator|TestChainlinkAggregator|TestContractWrapper|TestDydxUser|TestEth2Dai|TestEth2DaiBridge|TestFramework|TestMainnetAggregatorFills|TestSignatureValidationWallet|TestUniswapBridge|TestUniswapExchange|TestUniswapExchangeFactory).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
@@ -51,24 +51,25 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.2.0",
|
||||
"@0x/contract-addresses": "^4.5.0",
|
||||
"@0x/contract-wrappers": "^13.5.0",
|
||||
"@0x/contracts-broker": "^1.0.2",
|
||||
"@0x/contracts-coordinator": "^3.1.0",
|
||||
"@0x/contracts-dev-utils": "^1.1.0",
|
||||
"@0x/contracts-exchange-forwarder": "^4.2.0",
|
||||
"@0x/contracts-exchange-libs": "^4.3.0",
|
||||
"@0x/contracts-extensions": "^6.1.0",
|
||||
"@0x/contracts-gen": "^2.0.7",
|
||||
"@0x/contracts-utils": "^4.3.0",
|
||||
"@0x/abi-gen": "^5.2.2",
|
||||
"@0x/contract-addresses": "^4.7.0",
|
||||
"@0x/contract-wrappers": "^13.6.1",
|
||||
"@0x/contracts-broker": "^1.1.2",
|
||||
"@0x/contracts-coordinator": "^3.1.3",
|
||||
"@0x/contracts-dev-utils": "^1.3.1",
|
||||
"@0x/contracts-erc20-bridge-sampler": "^1.4.2",
|
||||
"@0x/contracts-exchange-forwarder": "^4.2.3",
|
||||
"@0x/contracts-exchange-libs": "^4.3.3",
|
||||
"@0x/contracts-extensions": "^6.1.3",
|
||||
"@0x/contracts-gen": "^2.0.8",
|
||||
"@0x/contracts-utils": "^4.4.1",
|
||||
"@0x/coordinator-server": "^1.0.5",
|
||||
"@0x/dev-utils": "^3.2.0",
|
||||
"@0x/migrations": "^6.1.0",
|
||||
"@0x/order-utils": "^10.2.0",
|
||||
"@0x/sol-compiler": "^4.0.7",
|
||||
"@0x/dev-utils": "^3.2.1",
|
||||
"@0x/migrations": "^6.2.2",
|
||||
"@0x/order-utils": "^10.2.2",
|
||||
"@0x/sol-compiler": "^4.0.8",
|
||||
"@0x/tslint-config": "^4.0.0",
|
||||
"@0x/web3-wrapper": "^7.0.6",
|
||||
"@0x/web3-wrapper": "^7.0.7",
|
||||
"@azure/core-asynciterator-polyfill": "^1.0.0",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^5.2.7",
|
||||
@@ -91,19 +92,19 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/asset-swapper": "^4.1.2",
|
||||
"@0x/base-contract": "^6.2.0",
|
||||
"@0x/contracts-asset-proxy": "^3.2.0",
|
||||
"@0x/contracts-erc1155": "^2.1.0",
|
||||
"@0x/contracts-erc20": "^3.1.0",
|
||||
"@0x/contracts-erc721": "^3.1.0",
|
||||
"@0x/contracts-exchange": "^3.2.0",
|
||||
"@0x/contracts-multisig": "^4.1.0",
|
||||
"@0x/contracts-staking": "^2.0.7",
|
||||
"@0x/contracts-test-utils": "^5.1.4",
|
||||
"@0x/asset-swapper": "^4.3.1",
|
||||
"@0x/base-contract": "^6.2.1",
|
||||
"@0x/contracts-asset-proxy": "^3.2.3",
|
||||
"@0x/contracts-erc1155": "^2.1.3",
|
||||
"@0x/contracts-erc20": "^3.1.3",
|
||||
"@0x/contracts-erc721": "^3.1.3",
|
||||
"@0x/contracts-exchange": "^3.2.3",
|
||||
"@0x/contracts-multisig": "^4.1.3",
|
||||
"@0x/contracts-staking": "^2.0.10",
|
||||
"@0x/contracts-test-utils": "^5.3.0",
|
||||
"@0x/types": "^3.1.2",
|
||||
"@0x/typescript-typings": "^5.0.2",
|
||||
"@0x/utils": "^5.4.0",
|
||||
"@0x/utils": "^5.4.1",
|
||||
"ethereum-types": "^3.1.0",
|
||||
"ethereumjs-util": "^6.2.0",
|
||||
"lodash": "^4.17.11"
|
||||
|
58
contracts/integrations/src/chainlink_utils.ts
Normal file
58
contracts/integrations/src/chainlink_utils.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { constants } from '@0x/contracts-test-utils';
|
||||
import { assetDataUtils } from '@0x/order-utils';
|
||||
import { StaticCallAssetData } from '@0x/types';
|
||||
import { AbiEncoder, BigNumber } from '@0x/utils';
|
||||
|
||||
export interface StopLimitParameters {
|
||||
oracle: string;
|
||||
minPrice: BigNumber;
|
||||
maxPrice: BigNumber;
|
||||
}
|
||||
|
||||
const stopLimitDataEncoder = AbiEncoder.create([
|
||||
{ name: 'oracle', type: 'address' },
|
||||
{ name: 'minPrice', type: 'int256' },
|
||||
{ name: 'maxPrice', type: 'int256' },
|
||||
]);
|
||||
|
||||
const stopLimitMethodEncoder = AbiEncoder.createMethod('checkStopLimit', [{ name: 'stopLimitData', type: 'bytes' }]);
|
||||
|
||||
/**
|
||||
* Encodes the given stop limit data parameters into the bytes format expected by the
|
||||
* ChainlinkStopLimit contract.
|
||||
*/
|
||||
export function encodeChainlinkStopLimitData(params: StopLimitParameters): string {
|
||||
return stopLimitDataEncoder.encode(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the given stop limit data parameters into StaticCall asset data so that it can be used
|
||||
* in a 0x order.
|
||||
*/
|
||||
export function encodeStopLimitStaticCallData(chainlinkStopLimitAddress: string, params: StopLimitParameters): string {
|
||||
const staticCallData = stopLimitMethodEncoder.encode({
|
||||
stopLimitData: encodeChainlinkStopLimitData(params),
|
||||
});
|
||||
return assetDataUtils.encodeStaticCallAssetData(
|
||||
chainlinkStopLimitAddress,
|
||||
staticCallData,
|
||||
constants.KECCAK256_NULL,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes stop limit data parameters from the bytes format expected by the ChainlinkStopLimit contract.
|
||||
*/
|
||||
export function decodeChainlinkStopLimitData(stopLimitData: string): StopLimitParameters {
|
||||
return stopLimitDataEncoder.decode(stopLimitData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes stop limit data parameters from stop limit StaticCall asset data.
|
||||
*/
|
||||
export function decodeStopLimitStaticCallData(assetData: string): StopLimitParameters {
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const { staticCallData } = assetDataUtils.decodeAssetDataOrThrow(assetData) as StaticCallAssetData;
|
||||
const stopLimitData = stopLimitMethodEncoder.strictDecode<string>(staticCallData);
|
||||
return decodeChainlinkStopLimitData(stopLimitData);
|
||||
}
|
@@ -1,2 +1,3 @@
|
||||
export { artifacts } from './artifacts';
|
||||
export * from './wrappers';
|
||||
export * from './chainlink_utils';
|
||||
|
@@ -5,6 +5,9 @@
|
||||
*/
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as ChainlinkStopLimit from '../test/generated-artifacts/ChainlinkStopLimit.json';
|
||||
import * as IChainlinkAggregator from '../test/generated-artifacts/IChainlinkAggregator.json';
|
||||
import * as TestChainlinkAggregator from '../test/generated-artifacts/TestChainlinkAggregator.json';
|
||||
import * as TestContractWrapper from '../test/generated-artifacts/TestContractWrapper.json';
|
||||
import * as TestDydxUser from '../test/generated-artifacts/TestDydxUser.json';
|
||||
import * as TestEth2Dai from '../test/generated-artifacts/TestEth2Dai.json';
|
||||
@@ -16,6 +19,9 @@ import * as TestUniswapBridge from '../test/generated-artifacts/TestUniswapBridg
|
||||
import * as TestUniswapExchange from '../test/generated-artifacts/TestUniswapExchange.json';
|
||||
import * as TestUniswapExchangeFactory from '../test/generated-artifacts/TestUniswapExchangeFactory.json';
|
||||
export const artifacts = {
|
||||
ChainlinkStopLimit: ChainlinkStopLimit as ContractArtifact,
|
||||
IChainlinkAggregator: IChainlinkAggregator as ContractArtifact,
|
||||
TestChainlinkAggregator: TestChainlinkAggregator as ContractArtifact,
|
||||
TestContractWrapper: TestContractWrapper as ContractArtifact,
|
||||
TestDydxUser: TestDydxUser as ContractArtifact,
|
||||
TestEth2Dai: TestEth2Dai as ContractArtifact,
|
||||
|
@@ -0,0 +1,37 @@
|
||||
import { artifacts, ERC20BridgeSamplerContract } from '@0x/contracts-erc20-bridge-sampler';
|
||||
import { blockchainTests, describe, expect, toBaseUnitAmount } from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
blockchainTests.fork.resets('Mainnet Sampler Tests', env => {
|
||||
let testContract: ERC20BridgeSamplerContract;
|
||||
before(async () => {
|
||||
testContract = await ERC20BridgeSamplerContract.deployFrom0xArtifactAsync(
|
||||
artifacts.ERC20BridgeSampler,
|
||||
env.provider,
|
||||
{ ...env.txDefaults, from: '0x6cc5f688a315f3dc28a7781717a9a798a59fda7b' },
|
||||
{},
|
||||
);
|
||||
});
|
||||
|
||||
describe('sampleSellsFromCurve()', () => {
|
||||
const curveAddress = '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51';
|
||||
const daiTokenIdx = new BigNumber(0);
|
||||
const usdcTokenIdx = new BigNumber(1);
|
||||
|
||||
it('samples sells from Curve DAI->USDC', async () => {
|
||||
const samples = await testContract
|
||||
.sampleSellsFromCurve(curveAddress, daiTokenIdx, usdcTokenIdx, [toBaseUnitAmount(1)])
|
||||
.callAsync();
|
||||
expect(samples.length).to.be.bignumber.greaterThan(0);
|
||||
expect(samples[0]).to.be.bignumber.greaterThan(0);
|
||||
});
|
||||
|
||||
it('samples sells from Curve USDC->DAI', async () => {
|
||||
const samples = await testContract
|
||||
.sampleSellsFromCurve(curveAddress, usdcTokenIdx, daiTokenIdx, [toBaseUnitAmount(1, 6)])
|
||||
.callAsync();
|
||||
expect(samples.length).to.be.bignumber.greaterThan(0);
|
||||
expect(samples[0]).to.be.bignumber.greaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user