@0x/dev-utils: Fix dydx min CR not being +1.
				
					
				
			`@0x/dev-utils`: Fix withdraw rate vs order conversion rate check .
This commit is contained in:
		@@ -42,8 +42,7 @@ library LibDydxBalance {
 | 
				
			|||||||
        address makerAddress;
 | 
					        address makerAddress;
 | 
				
			||||||
        address makerTokenAddress;
 | 
					        address makerTokenAddress;
 | 
				
			||||||
        address takerTokenAddress;
 | 
					        address takerTokenAddress;
 | 
				
			||||||
        uint256 makerAssetAmount;
 | 
					        int256 orderTakerToMakerRate;
 | 
				
			||||||
        uint256 takerAssetAmount;
 | 
					 | 
				
			||||||
        uint256[] accounts;
 | 
					        uint256[] accounts;
 | 
				
			||||||
        IDydxBridge.BridgeAction[] actions;
 | 
					        IDydxBridge.BridgeAction[] actions;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -66,9 +65,10 @@ library LibDydxBalance {
 | 
				
			|||||||
        if (!_areActionsWellFormed(info)) {
 | 
					        if (!_areActionsWellFormed(info)) {
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // If the rate we withdraw maker tokens is < 1, the asset proxy will
 | 
					        // If the rate we withdraw maker tokens is less than the order conversion
 | 
				
			||||||
        // throw because we will always transfer less maker tokens than asked.
 | 
					        // rate , the asset proxy will throw because we will always transfer
 | 
				
			||||||
        if (_getMakerTokenWithdrawRate(info) < D18.one()) {
 | 
					        // less maker tokens than asked.
 | 
				
			||||||
 | 
					        if (_getMakerTokenWithdrawRate(info) < info.orderTakerToMakerRate) {
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // The maker balance is the smaller of:
 | 
					        // The maker balance is the smaller of:
 | 
				
			||||||
@@ -154,11 +154,7 @@ library LibDydxBalance {
 | 
				
			|||||||
        returns (uint256 depositableMakerAmount)
 | 
					        returns (uint256 depositableMakerAmount)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        depositableMakerAmount = uint256(-1);
 | 
					        depositableMakerAmount = uint256(-1);
 | 
				
			||||||
        // The conversion rate from maker -> taker.
 | 
					        int256 orderMakerToTakerRate = D18.div(D18.one(), info.orderTakerToMakerRate);
 | 
				
			||||||
        int256 makerToTakerRate = D18.div(
 | 
					 | 
				
			||||||
            info.takerAssetAmount,
 | 
					 | 
				
			||||||
            info.makerAssetAmount
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        // Take the minimum maker amount from all deposits.
 | 
					        // Take the minimum maker amount from all deposits.
 | 
				
			||||||
        for (uint256 i = 0; i < info.actions.length; ++i) {
 | 
					        for (uint256 i = 0; i < info.actions.length; ++i) {
 | 
				
			||||||
            IDydxBridge.BridgeAction memory action = info.actions[i];
 | 
					            IDydxBridge.BridgeAction memory action = info.actions[i];
 | 
				
			||||||
@@ -172,7 +168,7 @@ library LibDydxBalance {
 | 
				
			|||||||
            // token.
 | 
					            // token.
 | 
				
			||||||
            address depositToken = info.dydx.getMarketTokenAddress(action.marketId);
 | 
					            address depositToken = info.dydx.getMarketTokenAddress(action.marketId);
 | 
				
			||||||
            if (info.takerTokenAddress != address(0) && depositToken == info.takerTokenAddress) {
 | 
					            if (info.takerTokenAddress != address(0) && depositToken == info.takerTokenAddress) {
 | 
				
			||||||
                depositRate = D18.sub(depositRate, makerToTakerRate);
 | 
					                depositRate = D18.sub(depositRate, orderMakerToTakerRate);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // If the deposit rate is > 0, we are limited by the transferrable
 | 
					            // If the deposit rate is > 0, we are limited by the transferrable
 | 
				
			||||||
            // token balance of the maker.
 | 
					            // token balance of the maker.
 | 
				
			||||||
@@ -241,7 +237,7 @@ library LibDydxBalance {
 | 
				
			|||||||
                _getActionRate(withdraw)
 | 
					                _getActionRate(withdraw)
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            // If the deposit to withdraw ratio is >= the minimum collateralization
 | 
					            // If the deposit to withdraw ratio is >= the minimum collateralization
 | 
				
			||||||
            // rate, then we will never become insolvent at these prices.
 | 
					            // ratio, then we will never become insolvent at these prices.
 | 
				
			||||||
            if (D18.div(dd, db) >= minCr) {
 | 
					            if (D18.div(dd, db) >= minCr) {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -279,8 +275,7 @@ library LibDydxBalance {
 | 
				
			|||||||
            (, info.takerTokenAddress) =
 | 
					            (, info.takerTokenAddress) =
 | 
				
			||||||
                LibAssetData.decodeERC20AssetData(order.takerAssetData);
 | 
					                LibAssetData.decodeERC20AssetData(order.takerAssetData);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        info.makerAssetAmount = order.makerAssetAmount;
 | 
					        info.orderTakerToMakerRate = D18.div(order.makerAssetAmount, order.takerAssetAmount);
 | 
				
			||||||
        info.takerAssetAmount = order.takerAssetAmount;
 | 
					 | 
				
			||||||
        (IDydxBridge.BridgeData memory bridgeData) =
 | 
					        (IDydxBridge.BridgeData memory bridgeData) =
 | 
				
			||||||
            abi.decode(rawBridgeData, (IDydxBridge.BridgeData));
 | 
					            abi.decode(rawBridgeData, (IDydxBridge.BridgeData));
 | 
				
			||||||
        info.accounts = bridgeData.accountNumbers;
 | 
					        info.accounts = bridgeData.accountNumbers;
 | 
				
			||||||
@@ -311,7 +306,7 @@ library LibDydxBalance {
 | 
				
			|||||||
        returns (int256 ratio)
 | 
					        returns (int256 ratio)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        IDydx.RiskParams memory riskParams = dydx.getRiskParams();
 | 
					        IDydx.RiskParams memory riskParams = dydx.getRiskParams();
 | 
				
			||||||
        return D18.toSigned(riskParams.marginRatio.value);
 | 
					        return D18.add(D18.one(), D18.toSigned(riskParams.marginRatio.value));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev Get the quote (USD) value of a rate within a market.
 | 
					    /// @dev Get the quote (USD) value of a rate within a market.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,7 +53,7 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
    const INSOLVENT_ACCOUNT_IDX = 2;
 | 
					    const INSOLVENT_ACCOUNT_IDX = 2;
 | 
				
			||||||
    const ZERO_BALANCE_ACCOUNT_IDX = 3;
 | 
					    const ZERO_BALANCE_ACCOUNT_IDX = 3;
 | 
				
			||||||
    const DYDX_CONFIG: TestDydxConfig = {
 | 
					    const DYDX_CONFIG: TestDydxConfig = {
 | 
				
			||||||
        marginRatio: fromTokenUnitAmount(MARGIN_RATIO, PRICE_DECIMALS),
 | 
					        marginRatio: fromTokenUnitAmount(MARGIN_RATIO - 1, PRICE_DECIMALS),
 | 
				
			||||||
        operators: [{ owner: ACCOUNT_OWNER, operator: BRIDGE_ADDRESS }],
 | 
					        operators: [{ owner: ACCOUNT_OWNER, operator: BRIDGE_ADDRESS }],
 | 
				
			||||||
        accounts: [
 | 
					        accounts: [
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -148,8 +148,7 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
        makerAddress: string;
 | 
					        makerAddress: string;
 | 
				
			||||||
        makerTokenAddress: string;
 | 
					        makerTokenAddress: string;
 | 
				
			||||||
        takerTokenAddress: string;
 | 
					        takerTokenAddress: string;
 | 
				
			||||||
        makerAssetAmount: BigNumber;
 | 
					        orderTakerToMakerRate: BigNumber;
 | 
				
			||||||
        takerAssetAmount: BigNumber;
 | 
					 | 
				
			||||||
        accounts: BigNumber[];
 | 
					        accounts: BigNumber[];
 | 
				
			||||||
        actions: DydxBridgeAction[];
 | 
					        actions: DydxBridgeAction[];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -161,8 +160,9 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
            makerAddress: ACCOUNT_OWNER,
 | 
					            makerAddress: ACCOUNT_OWNER,
 | 
				
			||||||
            makerTokenAddress: DYDX_CONFIG.markets[1].token,
 | 
					            makerTokenAddress: DYDX_CONFIG.markets[1].token,
 | 
				
			||||||
            takerTokenAddress: DYDX_CONFIG.markets[0].token,
 | 
					            takerTokenAddress: DYDX_CONFIG.markets[0].token,
 | 
				
			||||||
            makerAssetAmount: fromTokenUnitAmount(10, MAKER_DECIMALS),
 | 
					            orderTakerToMakerRate: fromTokenUnitAmount(
 | 
				
			||||||
            takerAssetAmount: fromTokenUnitAmount(5, TAKER_DECIMALS),
 | 
					                fromTokenUnitAmount(5, MAKER_DECIMALS).div(fromTokenUnitAmount(10, TAKER_DECIMALS)),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
            accounts: [DYDX_CONFIG.accounts[SOLVENT_ACCOUNT_IDX].accountId],
 | 
					            accounts: [DYDX_CONFIG.accounts[SOLVENT_ACCOUNT_IDX].accountId],
 | 
				
			||||||
            actions: [],
 | 
					            actions: [],
 | 
				
			||||||
            ...fields,
 | 
					            ...fields,
 | 
				
			||||||
@@ -537,8 +537,9 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
    blockchainTests.resets('_getDepositableMakerAmount()', () => {
 | 
					    blockchainTests.resets('_getDepositableMakerAmount()', () => {
 | 
				
			||||||
        it('returns infinite if no deposit action', async () => {
 | 
					        it('returns infinite if no deposit action', async () => {
 | 
				
			||||||
            const checkInfo = createBalanceCheckInfo({
 | 
					            const checkInfo = createBalanceCheckInfo({
 | 
				
			||||||
                takerAssetAmount: fromTokenUnitAmount(10, TAKER_DECIMALS),
 | 
					                orderTakerToMakerRate: fromTokenUnitAmount(
 | 
				
			||||||
                makerAssetAmount: fromTokenUnitAmount(100, MAKER_DECIMALS),
 | 
					                    fromTokenUnitAmount(100, MAKER_DECIMALS).div(fromTokenUnitAmount(10, TAKER_DECIMALS)),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
                actions: [],
 | 
					                actions: [],
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            const makerAssetFillAmount = await testContract.getDepositableMakerAmount(checkInfo).callAsync();
 | 
					            const makerAssetFillAmount = await testContract.getDepositableMakerAmount(checkInfo).callAsync();
 | 
				
			||||||
@@ -547,8 +548,9 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        it('returns infinite if deposit rate is zero', async () => {
 | 
					        it('returns infinite if deposit rate is zero', async () => {
 | 
				
			||||||
            const checkInfo = createBalanceCheckInfo({
 | 
					            const checkInfo = createBalanceCheckInfo({
 | 
				
			||||||
                takerAssetAmount: fromTokenUnitAmount(10, TAKER_DECIMALS),
 | 
					                orderTakerToMakerRate: fromTokenUnitAmount(
 | 
				
			||||||
                makerAssetAmount: fromTokenUnitAmount(100, MAKER_DECIMALS),
 | 
					                    fromTokenUnitAmount(100, MAKER_DECIMALS).div(fromTokenUnitAmount(10, TAKER_DECIMALS)),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
                actions: [
 | 
					                actions: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        actionType: DydxBridgeActionType.Deposit,
 | 
					                        actionType: DydxBridgeActionType.Deposit,
 | 
				
			||||||
@@ -565,8 +567,9 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        it('returns infinite if taker tokens cover the deposit rate', async () => {
 | 
					        it('returns infinite if taker tokens cover the deposit rate', async () => {
 | 
				
			||||||
            const checkInfo = createBalanceCheckInfo({
 | 
					            const checkInfo = createBalanceCheckInfo({
 | 
				
			||||||
                takerAssetAmount: fromTokenUnitAmount(10, TAKER_DECIMALS),
 | 
					                orderTakerToMakerRate: fromTokenUnitAmount(
 | 
				
			||||||
                makerAssetAmount: fromTokenUnitAmount(100, MAKER_DECIMALS),
 | 
					                    fromTokenUnitAmount(100, MAKER_DECIMALS).div(fromTokenUnitAmount(10, TAKER_DECIMALS)),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
                actions: [
 | 
					                actions: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        actionType: DydxBridgeActionType.Deposit,
 | 
					                        actionType: DydxBridgeActionType.Deposit,
 | 
				
			||||||
@@ -586,8 +589,9 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
            const exchangeRate = 0.1;
 | 
					            const exchangeRate = 0.1;
 | 
				
			||||||
            const depositRate = Math.random() + exchangeRate;
 | 
					            const depositRate = Math.random() + exchangeRate;
 | 
				
			||||||
            const checkInfo = createBalanceCheckInfo({
 | 
					            const checkInfo = createBalanceCheckInfo({
 | 
				
			||||||
                takerAssetAmount: fromTokenUnitAmount(exchangeRate, TAKER_DECIMALS),
 | 
					                orderTakerToMakerRate: fromTokenUnitAmount(
 | 
				
			||||||
                makerAssetAmount: fromTokenUnitAmount(1, MAKER_DECIMALS),
 | 
					                    fromTokenUnitAmount(1, MAKER_DECIMALS).div(fromTokenUnitAmount(exchangeRate, TAKER_DECIMALS)),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
                actions: [
 | 
					                actions: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        actionType: DydxBridgeActionType.Deposit,
 | 
					                        actionType: DydxBridgeActionType.Deposit,
 | 
				
			||||||
@@ -619,8 +623,7 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
            const checkInfo = createBalanceCheckInfo({
 | 
					            const checkInfo = createBalanceCheckInfo({
 | 
				
			||||||
                // The `takerTokenAddress` will be zero if the asset is not an ERC20.
 | 
					                // The `takerTokenAddress` will be zero if the asset is not an ERC20.
 | 
				
			||||||
                takerTokenAddress: constants.NULL_ADDRESS,
 | 
					                takerTokenAddress: constants.NULL_ADDRESS,
 | 
				
			||||||
                takerAssetAmount: new BigNumber(1),
 | 
					                orderTakerToMakerRate: fromTokenUnitAmount(fromTokenUnitAmount(100, MAKER_DECIMALS)),
 | 
				
			||||||
                makerAssetAmount: fromTokenUnitAmount(100, MAKER_DECIMALS),
 | 
					 | 
				
			||||||
                actions: [
 | 
					                actions: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        actionType: DydxBridgeActionType.Deposit,
 | 
					                        actionType: DydxBridgeActionType.Deposit,
 | 
				
			||||||
@@ -652,8 +655,9 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
                takerTokenAddress: randomAddress(),
 | 
					                takerTokenAddress: randomAddress(),
 | 
				
			||||||
                // These amounts should be effectively ignored in the final computation
 | 
					                // These amounts should be effectively ignored in the final computation
 | 
				
			||||||
                // because the token being deposited is not the taker token.
 | 
					                // because the token being deposited is not the taker token.
 | 
				
			||||||
                takerAssetAmount: fromTokenUnitAmount(10, TAKER_DECIMALS),
 | 
					                orderTakerToMakerRate: fromTokenUnitAmount(
 | 
				
			||||||
                makerAssetAmount: fromTokenUnitAmount(100, MAKER_DECIMALS),
 | 
					                    fromTokenUnitAmount(100, MAKER_DECIMALS).div(fromTokenUnitAmount(10, TAKER_DECIMALS)),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
                actions: [
 | 
					                actions: [
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        actionType: DydxBridgeActionType.Deposit,
 | 
					                        actionType: DydxBridgeActionType.Deposit,
 | 
				
			||||||
@@ -672,8 +676,9 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
            // The taker tokens getting exchanged in will only partially cover the deposit.
 | 
					            // The taker tokens getting exchanged in will only partially cover the deposit.
 | 
				
			||||||
            const exchangeRate = 0.1;
 | 
					            const exchangeRate = 0.1;
 | 
				
			||||||
            const checkInfo = createBalanceCheckInfo({
 | 
					            const checkInfo = createBalanceCheckInfo({
 | 
				
			||||||
                takerAssetAmount: fromTokenUnitAmount(exchangeRate, TAKER_DECIMALS),
 | 
					                orderTakerToMakerRate: fromTokenUnitAmount(
 | 
				
			||||||
                makerAssetAmount: fromTokenUnitAmount(1, MAKER_DECIMALS),
 | 
					                    fromTokenUnitAmount(1, MAKER_DECIMALS).div(fromTokenUnitAmount(exchangeRate, TAKER_DECIMALS)),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
                actions: [
 | 
					                actions: [
 | 
				
			||||||
                    // Technically, deposits of the same token are not allowed, but the
 | 
					                    // Technically, deposits of the same token are not allowed, but the
 | 
				
			||||||
                    // check isn't done in this function so we'll do this to simulate
 | 
					                    // check isn't done in this function so we'll do this to simulate
 | 
				
			||||||
@@ -728,8 +733,7 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
                const exchangeRate = 0.1;
 | 
					                const exchangeRate = 0.1;
 | 
				
			||||||
                const depositRate = Math.random() + exchangeRate;
 | 
					                const depositRate = Math.random() + exchangeRate;
 | 
				
			||||||
                const checkInfo = createBalanceCheckInfo({
 | 
					                const checkInfo = createBalanceCheckInfo({
 | 
				
			||||||
                    takerAssetAmount: fromTokenUnitAmount(exchangeRate, TAKER_DECIMALS),
 | 
					                    orderTakerToMakerRate: fromTokenUnitAmount(fromTokenUnitAmount(1 / exchangeRate, MAKER_DECIMALS)),
 | 
				
			||||||
                    makerAssetAmount: fromTokenUnitAmount(1, MAKER_DECIMALS),
 | 
					 | 
				
			||||||
                    actions: [
 | 
					                    actions: [
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            actionType: DydxBridgeActionType.Deposit,
 | 
					                            actionType: DydxBridgeActionType.Deposit,
 | 
				
			||||||
@@ -756,8 +760,7 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
                const exchangeRate = 0.1;
 | 
					                const exchangeRate = 0.1;
 | 
				
			||||||
                const depositRate = Math.random() + exchangeRate;
 | 
					                const depositRate = Math.random() + exchangeRate;
 | 
				
			||||||
                const checkInfo = createBalanceCheckInfo({
 | 
					                const checkInfo = createBalanceCheckInfo({
 | 
				
			||||||
                    takerAssetAmount: fromTokenUnitAmount(exchangeRate, TAKER_DECIMALS),
 | 
					                    orderTakerToMakerRate: fromTokenUnitAmount(fromTokenUnitAmount(1 / exchangeRate, MAKER_DECIMALS)),
 | 
				
			||||||
                    makerAssetAmount: fromTokenUnitAmount(1, MAKER_DECIMALS),
 | 
					 | 
				
			||||||
                    actions: [
 | 
					                    actions: [
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            actionType: DydxBridgeActionType.Deposit,
 | 
					                            actionType: DydxBridgeActionType.Deposit,
 | 
				
			||||||
@@ -1085,7 +1088,7 @@ blockchainTests('LibDydxBalance', env => {
 | 
				
			|||||||
            senderAddress: constants.NULL_ADDRESS,
 | 
					            senderAddress: constants.NULL_ADDRESS,
 | 
				
			||||||
            makerFee: getRandomInteger(1, constants.MAX_UINT256),
 | 
					            makerFee: getRandomInteger(1, constants.MAX_UINT256),
 | 
				
			||||||
            takerFee: getRandomInteger(1, constants.MAX_UINT256),
 | 
					            takerFee: getRandomInteger(1, constants.MAX_UINT256),
 | 
				
			||||||
            makerAssetAmount: fromTokenUnitAmount(100, TAKER_DECIMALS),
 | 
					            makerAssetAmount: fromTokenUnitAmount(100, MAKER_DECIMALS),
 | 
				
			||||||
            takerAssetAmount: fromTokenUnitAmount(10, TAKER_DECIMALS),
 | 
					            takerAssetAmount: fromTokenUnitAmount(10, TAKER_DECIMALS),
 | 
				
			||||||
            makerAssetData: createBridgeAssetData(makerTokenAddress, BRIDGE_ADDRESS),
 | 
					            makerAssetData: createBridgeAssetData(makerTokenAddress, BRIDGE_ADDRESS),
 | 
				
			||||||
            takerAssetData: createERC20AssetData(takerTokenAddress),
 | 
					            takerAssetData: createERC20AssetData(takerTokenAddress),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user