From 52a298305b138633b422c191b3399df5ecee4e4a Mon Sep 17 00:00:00 2001 From: Lawrence Forman Date: Thu, 6 Feb 2020 11:36:37 -0500 Subject: [PATCH] `@0x/contracts-asset-proxy`: Add `getMarketMarginPremium()` to `IDydx`. `@0x/contracts-dev-utils`: Handle dydx market premiums. --- .../asset-proxy/contracts/src/interfaces/IDydx.sol | 9 +++++++++ .../asset-proxy/contracts/test/TestDydxBridge.sol | 7 +++++++ contracts/dev-utils/contracts/src/D18.sol | 10 ++++++++++ contracts/dev-utils/contracts/src/LibDydxBalance.sol | 10 ++++++++++ contracts/dev-utils/contracts/test/TestDydx.sol | 9 +++++++++ 5 files changed, 45 insertions(+) diff --git a/contracts/asset-proxy/contracts/src/interfaces/IDydx.sol b/contracts/asset-proxy/contracts/src/interfaces/IDydx.sol index 8b353ad6ac..1ec67a2dfe 100644 --- a/contracts/asset-proxy/contracts/src/interfaces/IDydx.sol +++ b/contracts/asset-proxy/contracts/src/interfaces/IDydx.sol @@ -166,6 +166,15 @@ interface IDydx { 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 diff --git a/contracts/asset-proxy/contracts/test/TestDydxBridge.sol b/contracts/asset-proxy/contracts/test/TestDydxBridge.sol index ce3f4f8b78..d23425b865 100644 --- a/contracts/asset-proxy/contracts/test/TestDydxBridge.sol +++ b/contracts/asset-proxy/contracts/test/TestDydxBridge.sol @@ -210,6 +210,13 @@ contract TestDydxBridge is returns (Price memory price) {} + /// @dev Unsused + function getMarketMarginPremium(uint256 marketId) + external + view + returns (IDydx.D256 memory premium) + {} + /// @dev Unused. function getAdjustedAccountValues( AccountInfo calldata account diff --git a/contracts/dev-utils/contracts/src/D18.sol b/contracts/dev-utils/contracts/src/D18.sol index f491976186..9334f3057e 100644 --- a/contracts/dev-utils/contracts/src/D18.sol +++ b/contracts/dev-utils/contracts/src/D18.sol @@ -57,6 +57,16 @@ library D18 { r = _add(int256(a), b); } + /// @dev Add two decimals. + function add(int256 a, uint256 b) + internal + pure + returns (int256 r) + { + require(int256(b) >= 0, "D18/DECIMAL_VALUE_TOO_BIG"); + r = _add(a, int256(b)); + } + /// @dev Add two decimals. function add(uint256 a, uint256 b) internal diff --git a/contracts/dev-utils/contracts/src/LibDydxBalance.sol b/contracts/dev-utils/contracts/src/LibDydxBalance.sol index 20095ef30e..822bd20bf3 100644 --- a/contracts/dev-utils/contracts/src/LibDydxBalance.sol +++ b/contracts/dev-utils/contracts/src/LibDydxBalance.sol @@ -339,6 +339,16 @@ library LibDydxBalance { } // 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 Returns the conversion rate for an action, expressed as units diff --git a/contracts/dev-utils/contracts/test/TestDydx.sol b/contracts/dev-utils/contracts/test/TestDydx.sol index be251af314..c2e771ca47 100644 --- a/contracts/dev-utils/contracts/test/TestDydx.sol +++ b/contracts/dev-utils/contracts/test/TestDydx.sol @@ -129,6 +129,15 @@ contract TestDydx { } } + function getMarketMarginPremium(uint256) + external + view + returns (IDydx.D256 memory premium) + { + // Return 0. + return premium; + } + function getMarketPrice( uint256 marketId )