@dolomite-exchange/dolomite-margin 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/build/contracts/Account.json +11 -11
  2. package/build/contracts/Actions.json +11 -11
  3. package/build/contracts/Address.json +1 -1
  4. package/build/contracts/Admin.json +23 -23
  5. package/build/contracts/AdminImpl.json +35 -307
  6. package/build/contracts/AdvancedMath.json +7 -7
  7. package/build/contracts/AmmRebalancerProxy.json +577 -621
  8. package/build/contracts/AmmRebalancerProxyV1.json +78 -32
  9. package/build/contracts/Babylonian.json +1 -1
  10. package/build/contracts/Bits.json +9 -9
  11. package/build/contracts/Cache.json +13 -13
  12. package/build/contracts/ChainlinkPriceOracleV1.json +16 -16
  13. package/build/contracts/Context.json +1 -1
  14. package/build/contracts/CustomTestToken.json +9 -9
  15. package/build/contracts/Decimal.json +9 -9
  16. package/build/contracts/DelayedMultiSig.json +9 -9
  17. package/build/contracts/DolomiteAmmERC20.json +11 -11
  18. package/build/contracts/DolomiteAmmFactory.json +14 -52
  19. package/build/contracts/DolomiteAmmLibrary.json +24 -24
  20. package/build/contracts/DolomiteAmmPair.json +27 -27
  21. package/build/contracts/DolomiteAmmRouterProxy.json +30 -363
  22. package/build/contracts/DolomiteMargin.json +21 -67
  23. package/build/contracts/DoubleExponentInterestSetter.json +15 -21
  24. package/build/contracts/EnumerableSet.json +7 -7
  25. package/build/contracts/ErroringOmiseToken.json +9 -9
  26. package/build/contracts/ErroringToken.json +10 -10
  27. package/build/contracts/Events.json +17 -17
  28. package/build/contracts/ExcessivelySafeCall.json +35 -35
  29. package/build/contracts/Exchange.json +15 -15
  30. package/build/contracts/Expiry.json +36 -36
  31. package/build/contracts/Getters.json +33 -33
  32. package/build/contracts/IAutoTrader.json +9 -9
  33. package/build/contracts/ICallee.json +7 -7
  34. package/build/contracts/IChainlinkAggregator.json +5 -5
  35. package/build/contracts/IDolomiteAmmERC20.json +5 -5
  36. package/build/contracts/IDolomiteAmmFactory.json +9 -9
  37. package/build/contracts/IDolomiteAmmPair.json +9 -9
  38. package/build/contracts/IDolomiteMargin.json +23 -23
  39. package/build/contracts/IERC20.json +1 -1
  40. package/build/contracts/IERC20Detailed.json +5 -5
  41. package/build/contracts/IExchangeWrapper.json +5 -5
  42. package/build/contracts/IExpiry.json +9 -9
  43. package/build/contracts/IInterestSetter.json +7 -7
  44. package/build/contracts/ILiquidationCallback.json +7 -7
  45. package/build/contracts/IMakerOracle.json +5 -5
  46. package/build/contracts/IOasisDex.json +5 -5
  47. package/build/contracts/IPriceOracle.json +7 -7
  48. package/build/contracts/IRecyclable.json +9 -9
  49. package/build/contracts/ITransferProxy.json +5 -5
  50. package/build/contracts/IUniswapV2Callee.json +5 -5
  51. package/build/contracts/IUniswapV2Factory.json +5 -5
  52. package/build/contracts/IUniswapV2Pair.json +5 -5
  53. package/build/contracts/IUniswapV2Router.json +5 -5
  54. package/build/contracts/IWETH.json +5 -5
  55. package/build/contracts/Interest.json +15 -15
  56. package/build/contracts/LiquidateOrVaporizeImpl.json +32 -83
  57. package/build/contracts/LiquidatorProxyHelper.json +23 -23
  58. package/build/contracts/LiquidatorProxyV1.json +30 -36
  59. package/build/contracts/LiquidatorProxyV1WithAmm.json +49 -105
  60. package/build/contracts/Math.json +1 -1
  61. package/build/contracts/Migrations.json +8 -14
  62. package/build/contracts/Monetary.json +7 -7
  63. package/build/contracts/MultiCall.json +8 -14
  64. package/build/contracts/MultiSig.json +7 -7
  65. package/build/contracts/OmiseToken.json +8 -8
  66. package/build/contracts/OnlyDolomiteMargin.json +11 -11
  67. package/build/contracts/Operation.json +15 -15
  68. package/build/contracts/OperationImpl.json +39 -47
  69. package/build/contracts/Ownable.json +1 -1
  70. package/build/contracts/PartiallyDelayedMultiSig.json +9 -9
  71. package/build/contracts/PayableProxy.json +17 -23
  72. package/build/contracts/Permission.json +11 -11
  73. package/build/contracts/PolynomialInterestSetter.json +13 -13
  74. package/build/contracts/RecyclableTokenProxy.json +25 -25
  75. package/build/contracts/ReentrancyGuard.json +1 -1
  76. package/build/contracts/Require.json +7 -7
  77. package/build/contracts/SafeERC20.json +1 -1
  78. package/build/contracts/SafeETH.json +7 -7
  79. package/build/contracts/SafeLiquidationCallback.json +17 -17
  80. package/build/contracts/SafeMath.json +1 -1
  81. package/build/contracts/SignedOperationProxy.json +21 -104
  82. package/build/contracts/SimpleFeeOwner.json +18 -63
  83. package/build/contracts/State.json +9 -9
  84. package/build/contracts/Storage.json +37 -37
  85. package/build/contracts/TestAmmRebalancerProxy.json +32 -58
  86. package/build/contracts/TestAutoTrader.json +22 -22
  87. package/build/contracts/TestBtcUsdChainlinkAggregator.json +10 -10
  88. package/build/contracts/TestCallee.json +19 -19
  89. package/build/contracts/TestChainlinkPriceOracleV1.json +10 -94
  90. package/build/contracts/TestCounter.json +7 -7
  91. package/build/contracts/TestDaiUsdChainlinkAggregator.json +11 -11
  92. package/build/contracts/TestDolomiteMargin.json +22 -22
  93. package/build/contracts/TestDoubleExponentInterestSetter.json +10 -10
  94. package/build/contracts/TestEthUsdChainlinkAggregator.json +11 -11
  95. package/build/contracts/TestExchangeWrapper.json +28 -28
  96. package/build/contracts/TestInterestSetter.json +13 -13
  97. package/build/contracts/TestLib.json +22 -22
  98. package/build/contracts/TestLinkUsdChainlinkAggregator.json +11 -11
  99. package/build/contracts/TestLiquidateCallback.json +719 -719
  100. package/build/contracts/TestLiquidationCallback.json +13 -13
  101. package/build/contracts/TestLrcEthChainlinkAggregator.json +11 -11
  102. package/build/contracts/TestMakerOracle.json +10 -10
  103. package/build/contracts/TestMaticUsdChainlinkAggregator.json +10 -10
  104. package/build/contracts/TestOasisDex.json +12 -12
  105. package/build/contracts/TestOperationImpl.json +14 -14
  106. package/build/contracts/TestPolynomialInterestSetter.json +10 -10
  107. package/build/contracts/TestPriceAggregator.json +9 -9
  108. package/build/contracts/TestPriceOracle.json +13 -13
  109. package/build/contracts/TestRecyclableToken.json +9 -9
  110. package/build/contracts/TestSimpleCallee.json +15 -15
  111. package/build/contracts/TestToken.json +9 -9
  112. package/build/contracts/TestTrader.json +17 -17
  113. package/build/contracts/TestUniswapAmmRebalancerProxy.json +16 -16
  114. package/build/contracts/TestUsdcUsdChainlinkAggregator.json +11 -11
  115. package/build/contracts/TestWETH.json +9 -9
  116. package/build/contracts/Time.json +9 -9
  117. package/build/contracts/Token.json +9 -9
  118. package/build/contracts/TokenA.json +10 -10
  119. package/build/contracts/TokenB.json +10 -10
  120. package/build/contracts/TokenC.json +10 -10
  121. package/build/contracts/TokenD.json +10 -10
  122. package/build/contracts/TokenE.json +10 -10
  123. package/build/contracts/TokenF.json +10 -10
  124. package/build/contracts/TransferProxy.json +22 -28
  125. package/build/contracts/TypedSignature.json +9 -9
  126. package/build/contracts/Types.json +9 -9
  127. package/build/contracts/UQ112x112.json +7 -7
  128. package/build/contracts/UniswapV2ERC20.json +7 -7
  129. package/build/contracts/UniswapV2Factory.json +12 -12
  130. package/build/contracts/UniswapV2Library.json +20 -20
  131. package/build/contracts/UniswapV2Pair.json +17 -17
  132. package/build/contracts/UniswapV2Router02.json +16 -16
  133. package/build/contracts/WETH9.json +1 -1
  134. package/contracts/external/amm/DolomiteAmmERC20.sol +135 -0
  135. package/contracts/external/amm/DolomiteAmmFactory.sol +122 -0
  136. package/contracts/external/amm/DolomiteAmmPair.sol +573 -0
  137. package/contracts/external/amm/SimpleFeeOwner.sol +107 -0
  138. package/contracts/external/helpers/LiquidatorProxyHelper.sol +252 -0
  139. package/contracts/external/helpers/OnlyDolomiteMargin.sol +63 -0
  140. package/contracts/external/interestsetters/DoubleExponentInterestSetter.sol +212 -0
  141. package/contracts/external/interestsetters/PolynomialInterestSetter.sol +205 -0
  142. package/contracts/external/interfaces/IChainlinkAggregator.sol +33 -0
  143. package/contracts/external/interfaces/IDolomiteAmmERC20.sol +52 -0
  144. package/contracts/external/interfaces/IDolomiteAmmFactory.sol +42 -0
  145. package/contracts/external/interfaces/IDolomiteAmmPair.sol +116 -0
  146. package/contracts/external/interfaces/IExpiry.sol +70 -0
  147. package/contracts/external/interfaces/IMakerOracle.sol +52 -0
  148. package/contracts/external/interfaces/IOasisDex.sol +326 -0
  149. package/contracts/external/interfaces/ITransferProxy.sol +53 -0
  150. package/contracts/external/interfaces/IUniswapV2Router.sol +134 -0
  151. package/contracts/external/lib/AdvancedMath.sol +23 -0
  152. package/contracts/external/lib/DolomiteAmmLibrary.sol +323 -0
  153. package/contracts/external/lib/TypedSignature.sol +120 -0
  154. package/contracts/external/lib/UQ112x112.sol +22 -0
  155. package/contracts/external/multisig/DelayedMultiSig.sol +206 -0
  156. package/contracts/external/multisig/MultiSig.sol +571 -0
  157. package/contracts/external/multisig/PartiallyDelayedMultiSig.sol +174 -0
  158. package/contracts/external/oracles/ChainlinkPriceOracleV1.sol +197 -0
  159. package/contracts/external/oracles/TestChainlinkPriceOracleV1.sol +98 -0
  160. package/contracts/external/proxies/AmmRebalancerProxyV1.sol +465 -0
  161. package/contracts/external/proxies/DolomiteAmmRouterProxy.sol +877 -0
  162. package/contracts/external/proxies/LiquidatorProxyV1.sol +507 -0
  163. package/contracts/external/proxies/LiquidatorProxyV1WithAmm.sol +574 -0
  164. package/contracts/external/proxies/PayableProxy.sol +146 -0
  165. package/contracts/external/proxies/RecyclableTokenProxy.sol +463 -0
  166. package/contracts/external/proxies/SignedOperationProxy.sol +553 -0
  167. package/contracts/external/proxies/TransferProxy.sol +207 -0
  168. package/contracts/external/traders/Expiry.sol +532 -0
  169. package/contracts/external/uniswap-v2/UniswapV2ERC20.sol +118 -0
  170. package/contracts/external/uniswap-v2/UniswapV2Factory.sol +67 -0
  171. package/contracts/external/uniswap-v2/UniswapV2Pair.sol +283 -0
  172. package/contracts/external/uniswap-v2/UniswapV2Router02.sol +566 -0
  173. package/contracts/external/uniswap-v2/interfaces/IUniswapV2Callee.sol +13 -0
  174. package/contracts/external/uniswap-v2/interfaces/IUniswapV2Factory.sol +18 -0
  175. package/contracts/external/uniswap-v2/interfaces/IUniswapV2Pair.sol +67 -0
  176. package/contracts/external/uniswap-v2/interfaces/IWETH.sol +7 -0
  177. package/contracts/external/uniswap-v2/libraries/SafeETH.sol +29 -0
  178. package/contracts/external/uniswap-v2/libraries/UniswapV2Library.sol +117 -0
  179. package/contracts/external/utils/MultiCall.sol +95 -0
  180. package/contracts/protocol/impl/artifacts/OperationImpl.json +80 -0
  181. package/contracts/protocol/impl/artifacts/OperationImpl_metadata.json +193 -0
  182. package/dist/build/published_contracts/AdminImpl.json +2 -2
  183. package/dist/build/published_contracts/AmmRebalancerProxyV1.json +5 -0
  184. package/dist/build/published_contracts/ChainlinkPriceOracleV1.json +1 -1
  185. package/dist/build/published_contracts/DolomiteAmmFactory.json +1 -1
  186. package/dist/build/published_contracts/DolomiteAmmRouterProxy.json +1 -1
  187. package/dist/build/published_contracts/DoubleExponentInterestSetter.json +2 -2
  188. package/dist/build/published_contracts/Expiry.json +1 -1
  189. package/dist/build/published_contracts/LiquidatorProxyV1.json +1 -1
  190. package/dist/build/published_contracts/LiquidatorProxyV1WithAmm.json +1 -1
  191. package/dist/build/published_contracts/MultiCall.json +1 -1
  192. package/dist/build/published_contracts/PayableProxy.json +2 -2
  193. package/dist/build/published_contracts/SignedOperationProxy.json +2 -2
  194. package/dist/build/published_contracts/SimpleFeeOwner.json +1 -1
  195. package/dist/build/published_contracts/TestUniswapAmmRebalancerProxy.json +140 -0
  196. package/dist/build/published_contracts/TransferProxy.json +1 -1
  197. package/dist/src/lib/Contracts.d.ts +3 -1
  198. package/dist/src/lib/Contracts.js +7 -3
  199. package/dist/src/lib/Contracts.js.map +1 -1
  200. package/package.json +2 -1
@@ -0,0 +1,532 @@
1
+ /*
2
+
3
+ Copyright 2019 dYdX Trading Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ */
18
+
19
+ pragma solidity ^0.5.7;
20
+ pragma experimental ABIEncoderV2;
21
+
22
+ import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
23
+ import { Ownable } from "@openzeppelin/contracts/ownership/Ownable.sol";
24
+ import { Address } from "@openzeppelin/contracts/utils/Address.sol";
25
+ import { IAutoTrader } from "../../protocol/interfaces/IAutoTrader.sol";
26
+ import { ICallee } from "../../protocol/interfaces/ICallee.sol";
27
+ import { IDolomiteMargin } from "../../protocol/interfaces/IDolomiteMargin.sol";
28
+ import { ILiquidationCallback } from "../../protocol/interfaces/ILiquidationCallback.sol";
29
+ import { Account } from "../../protocol/lib/Account.sol";
30
+ import { Decimal } from "../../protocol/lib/Decimal.sol";
31
+ import { Math } from "../../protocol/lib/Math.sol";
32
+ import { Monetary } from "../../protocol/lib/Monetary.sol";
33
+ import { Require } from "../../protocol/lib/Require.sol";
34
+ import { SafeLiquidationCallback } from "../../protocol/lib/SafeLiquidationCallback.sol";
35
+ import { Time } from "../../protocol/lib/Time.sol";
36
+ import { Types } from "../../protocol/lib/Types.sol";
37
+ import { OnlyDolomiteMargin } from "../helpers/OnlyDolomiteMargin.sol";
38
+ import { IExpiry } from "../interfaces/IExpiry.sol";
39
+
40
+
41
+ /**
42
+ * @title Expiry
43
+ * @author dYdX
44
+ *
45
+ * Expiry contract that also allows approved senders to set expiry to be 28 days in the future.
46
+ */
47
+ contract Expiry is
48
+ Ownable,
49
+ OnlyDolomiteMargin,
50
+ IExpiry,
51
+ ICallee,
52
+ IAutoTrader
53
+ {
54
+ using Address for address;
55
+ using Math for uint256;
56
+ using SafeMath for uint32;
57
+ using SafeMath for uint256;
58
+ using Types for Types.Par;
59
+ using Types for Types.Wei;
60
+
61
+ // ============ Constants ============
62
+
63
+ bytes32 constant FILE = "Expiry";
64
+
65
+ // ============ Events ============
66
+
67
+ event ExpirySet(
68
+ address owner,
69
+ uint256 number,
70
+ uint256 marketId,
71
+ uint32 time
72
+ );
73
+
74
+ event LogExpiryRampTimeSet(
75
+ uint256 expiryRampTime
76
+ );
77
+
78
+ event LogSenderApproved(
79
+ address approver,
80
+ address sender,
81
+ uint32 minTimeDelta
82
+ );
83
+
84
+ // ============ Storage ============
85
+
86
+ // owner => number => market => time
87
+ mapping (address => mapping (uint256 => mapping (uint256 => uint32))) g_expiries;
88
+
89
+ // owner => sender => minimum time delta
90
+ mapping (address => mapping (address => uint32)) public g_approvedSender;
91
+
92
+ // time over which the liquidation ratio goes from zero to maximum
93
+ uint256 public g_expiryRampTime;
94
+
95
+ // ============ Constructor ============
96
+
97
+ constructor (
98
+ address dolomiteMargin,
99
+ uint256 expiryRampTime
100
+ )
101
+ public
102
+ OnlyDolomiteMargin(dolomiteMargin)
103
+ {
104
+ g_expiryRampTime = expiryRampTime;
105
+ }
106
+
107
+ // ============ Admin Functions ============
108
+
109
+ function ownerSetExpiryRampTime(
110
+ uint256 newExpiryRampTime
111
+ )
112
+ external
113
+ onlyOwner
114
+ {
115
+ emit LogExpiryRampTimeSet(newExpiryRampTime);
116
+ g_expiryRampTime = newExpiryRampTime;
117
+ }
118
+
119
+ // ============ Approval Functions ============
120
+
121
+ function approveSender(
122
+ address sender,
123
+ uint32 minTimeDelta
124
+ )
125
+ external
126
+ {
127
+ _setApproval(msg.sender, sender, minTimeDelta);
128
+ }
129
+
130
+ // ============ Only-DolomiteMargin Functions ============
131
+
132
+ function callFunction(
133
+ address /* sender */,
134
+ Account.Info memory account,
135
+ bytes memory data
136
+ )
137
+ public
138
+ onlyDolomiteMargin(msg.sender)
139
+ {
140
+ CallFunctionType callType = abi.decode(data, (CallFunctionType));
141
+ if (callType == CallFunctionType.SetExpiry) {
142
+ _callFunctionSetExpiry(account.owner, data);
143
+ } else {
144
+ _callFunctionSetApproval(account.owner, data);
145
+ }
146
+ }
147
+
148
+ function getTradeCost(
149
+ uint256 inputMarketId,
150
+ uint256 outputMarketId,
151
+ Account.Info memory makerAccount,
152
+ Account.Info memory /* takerAccount */,
153
+ Types.Par memory oldInputPar,
154
+ Types.Par memory newInputPar,
155
+ Types.Wei memory inputWei,
156
+ bytes memory data
157
+ )
158
+ public
159
+ onlyDolomiteMargin(msg.sender)
160
+ returns (Types.AssetAmount memory)
161
+ {
162
+ // return zero if input amount is zero
163
+ if (inputWei.isZero()) {
164
+ return Types.AssetAmount({
165
+ sign: true,
166
+ denomination: Types.AssetDenomination.Par,
167
+ ref: Types.AssetReference.Delta,
168
+ value: 0
169
+ });
170
+ }
171
+
172
+ (uint256 owedMarketId, uint32 maxExpiry) = abi.decode(data, (uint256, uint32));
173
+
174
+ uint32 expiry = getExpiry(makerAccount, owedMarketId);
175
+
176
+ // validate expiry
177
+ Require.that(
178
+ expiry != 0,
179
+ FILE,
180
+ "Expiry not set",
181
+ makerAccount.owner,
182
+ makerAccount.number,
183
+ owedMarketId
184
+ );
185
+ Require.that(
186
+ expiry <= Time.currentTime(),
187
+ FILE,
188
+ "Borrow not yet expired",
189
+ expiry
190
+ );
191
+ Require.that(
192
+ expiry <= maxExpiry,
193
+ FILE,
194
+ "Expiry past maxExpiry",
195
+ expiry
196
+ );
197
+
198
+ return _getTradeCostInternal(
199
+ DOLOMITE_MARGIN,
200
+ inputMarketId,
201
+ outputMarketId,
202
+ makerAccount,
203
+ oldInputPar,
204
+ newInputPar,
205
+ inputWei,
206
+ owedMarketId,
207
+ expiry
208
+ );
209
+ }
210
+
211
+ // ============ Getters ============
212
+
213
+ function getExpiry(
214
+ Account.Info memory account,
215
+ uint256 marketId
216
+ )
217
+ public
218
+ view
219
+ returns (uint32)
220
+ {
221
+ return g_expiries[account.owner][account.number][marketId];
222
+ }
223
+
224
+ function getSpreadAdjustedPrices(
225
+ uint256 heldMarketId,
226
+ uint256 owedMarketId,
227
+ uint32 expiry
228
+ )
229
+ public
230
+ view
231
+ returns (
232
+ Monetary.Price memory,
233
+ Monetary.Price memory
234
+ )
235
+ {
236
+ return _getSpreadAdjustedPrices(
237
+ DOLOMITE_MARGIN,
238
+ heldMarketId,
239
+ owedMarketId,
240
+ expiry
241
+ );
242
+ }
243
+
244
+ // ============ Private Functions ============
245
+
246
+ function _getSpreadAdjustedPrices(
247
+ IDolomiteMargin dolomiteMargin,
248
+ uint256 heldMarketId,
249
+ uint256 owedMarketId,
250
+ uint32 expiry
251
+ )
252
+ private
253
+ view
254
+ returns (
255
+ Monetary.Price memory,
256
+ Monetary.Price memory
257
+ )
258
+ {
259
+ Decimal.D256 memory spread = dolomiteMargin.getLiquidationSpreadForPair(
260
+ heldMarketId,
261
+ owedMarketId
262
+ );
263
+
264
+ uint256 expiryAge = Time.currentTime().sub(expiry);
265
+
266
+ if (expiryAge < g_expiryRampTime) {
267
+ spread.value = Math.getPartial(spread.value, expiryAge, g_expiryRampTime);
268
+ }
269
+
270
+ Monetary.Price memory heldPrice = dolomiteMargin.getMarketPrice(heldMarketId);
271
+ Monetary.Price memory owedPrice = dolomiteMargin.getMarketPrice(owedMarketId);
272
+ owedPrice.value = owedPrice.value.add(Decimal.mul(owedPrice.value, spread));
273
+
274
+ return (heldPrice, owedPrice);
275
+ }
276
+
277
+ function _callFunctionSetExpiry(
278
+ address sender,
279
+ bytes memory data
280
+ )
281
+ private
282
+ {
283
+ (
284
+ CallFunctionType callType,
285
+ SetExpiryArg[] memory expiries
286
+ ) = abi.decode(data, (CallFunctionType, SetExpiryArg[]));
287
+
288
+ assert(callType == CallFunctionType.SetExpiry);
289
+
290
+ for (uint256 i = 0; i < expiries.length; i++) {
291
+ SetExpiryArg memory exp = expiries[i];
292
+ if (exp.account.owner != sender) {
293
+ // don't do anything if sender is not approved for this action
294
+ uint32 minApprovedTimeDelta = g_approvedSender[exp.account.owner][sender];
295
+ if (minApprovedTimeDelta == 0 || exp.timeDelta < minApprovedTimeDelta) {
296
+ continue;
297
+ }
298
+ }
299
+
300
+ // if timeDelta is zero, interpret it as unset expiry
301
+ if (
302
+ exp.timeDelta != 0 &&
303
+ DOLOMITE_MARGIN.getAccountPar(exp.account, exp.marketId).isNegative()
304
+ ) {
305
+ // only change non-zero values if forceUpdate is true
306
+ if (exp.forceUpdate || getExpiry(exp.account, exp.marketId) == 0) {
307
+ uint32 newExpiryTime = Time.currentTime().add(exp.timeDelta).to32();
308
+ _setExpiry(exp.account, exp.marketId, newExpiryTime);
309
+ }
310
+ } else {
311
+ // timeDelta is zero or account has non-negative balance
312
+ _setExpiry(exp.account, exp.marketId, 0);
313
+ }
314
+ }
315
+ }
316
+
317
+ function _callFunctionSetApproval(
318
+ address sender,
319
+ bytes memory data
320
+ )
321
+ private
322
+ {
323
+ (
324
+ CallFunctionType callType,
325
+ SetApprovalArg memory approvalArg
326
+ ) = abi.decode(data, (CallFunctionType, SetApprovalArg));
327
+ assert(callType == CallFunctionType.SetApproval);
328
+ _setApproval(sender, approvalArg.sender, approvalArg.minTimeDelta);
329
+ }
330
+
331
+ function _getTradeCostInternal(
332
+ IDolomiteMargin dolomiteMargin,
333
+ uint256 inputMarketId,
334
+ uint256 outputMarketId,
335
+ Account.Info memory makerAccount,
336
+ Types.Par memory oldInputPar,
337
+ Types.Par memory newInputPar,
338
+ Types.Wei memory inputWei,
339
+ uint256 owedMarketId,
340
+ uint32 expiry
341
+ )
342
+ private
343
+ returns (Types.AssetAmount memory)
344
+ {
345
+ Types.AssetAmount memory output;
346
+ Types.Wei memory maxOutputWei = dolomiteMargin.getAccountWei(makerAccount, outputMarketId);
347
+
348
+ if (inputWei.isPositive()) {
349
+ Require.that(
350
+ inputMarketId == owedMarketId,
351
+ FILE,
352
+ "inputMarket mismatch",
353
+ inputMarketId
354
+ );
355
+ Require.that(
356
+ !newInputPar.isPositive(),
357
+ FILE,
358
+ "Borrows cannot be overpaid",
359
+ newInputPar.value
360
+ );
361
+ assert(oldInputPar.isNegative());
362
+ Require.that(
363
+ maxOutputWei.isPositive(),
364
+ FILE,
365
+ "Collateral must be positive",
366
+ outputMarketId,
367
+ maxOutputWei.value
368
+ );
369
+ output = _owedWeiToHeldWei(
370
+ dolomiteMargin,
371
+ inputWei,
372
+ outputMarketId,
373
+ inputMarketId,
374
+ expiry
375
+ );
376
+
377
+ // clear expiry if borrow is fully repaid
378
+ if (newInputPar.isZero()) {
379
+ _setExpiry(makerAccount, owedMarketId, 0);
380
+ }
381
+ } else {
382
+ Require.that(
383
+ outputMarketId == owedMarketId,
384
+ FILE,
385
+ "outputMarket mismatch",
386
+ outputMarketId
387
+ );
388
+ Require.that(
389
+ !newInputPar.isNegative(),
390
+ FILE,
391
+ "Collateral cannot be overused",
392
+ newInputPar.value
393
+ );
394
+ assert(oldInputPar.isPositive());
395
+ Require.that(
396
+ maxOutputWei.isNegative(),
397
+ FILE,
398
+ "Borrows must be negative",
399
+ outputMarketId,
400
+ maxOutputWei.value
401
+ );
402
+ output = _heldWeiToOwedWei(
403
+ dolomiteMargin,
404
+ inputWei,
405
+ inputMarketId,
406
+ outputMarketId,
407
+ expiry
408
+ );
409
+
410
+ // clear expiry if borrow is fully repaid
411
+ if (output.value == maxOutputWei.value) {
412
+ _setExpiry(makerAccount, owedMarketId, 0);
413
+ }
414
+ }
415
+
416
+ Require.that(
417
+ output.value <= maxOutputWei.value,
418
+ FILE,
419
+ "outputMarket too small",
420
+ output.value,
421
+ maxOutputWei.value
422
+ );
423
+ assert(output.sign != maxOutputWei.sign);
424
+
425
+ SafeLiquidationCallback.callLiquidateCallbackIfNecessary(
426
+ makerAccount,
427
+ owedMarketId == inputMarketId ? outputMarketId : inputMarketId,
428
+ owedMarketId == inputMarketId ? Types.Wei(output.sign, output.value) : inputWei,
429
+ owedMarketId,
430
+ owedMarketId == inputMarketId ? inputWei : Types.Wei(output.sign, output.value)
431
+ );
432
+
433
+ return output;
434
+ }
435
+
436
+ function _setExpiry(
437
+ Account.Info memory account,
438
+ uint256 marketId,
439
+ uint32 time
440
+ )
441
+ private
442
+ {
443
+ g_expiries[account.owner][account.number][marketId] = time;
444
+ emit ExpirySet(
445
+ account.owner,
446
+ account.number,
447
+ marketId,
448
+ time
449
+ );
450
+ }
451
+
452
+ function _setApproval(
453
+ address approver,
454
+ address sender,
455
+ uint32 minTimeDelta
456
+ )
457
+ private
458
+ {
459
+ g_approvedSender[approver][sender] = minTimeDelta;
460
+ emit LogSenderApproved(approver, sender, minTimeDelta);
461
+ }
462
+
463
+ function _heldWeiToOwedWei(
464
+ IDolomiteMargin dolomiteMargin,
465
+ Types.Wei memory heldWei,
466
+ uint256 heldMarketId,
467
+ uint256 owedMarketId,
468
+ uint32 expiry
469
+ )
470
+ private
471
+ view
472
+ returns (Types.AssetAmount memory)
473
+ {
474
+ (
475
+ Monetary.Price memory heldPrice,
476
+ Monetary.Price memory owedPrice
477
+ ) = _getSpreadAdjustedPrices(
478
+ dolomiteMargin,
479
+ heldMarketId,
480
+ owedMarketId,
481
+ expiry
482
+ );
483
+
484
+ uint256 owedAmount = Math.getPartialRoundUp(
485
+ heldWei.value,
486
+ heldPrice.value,
487
+ owedPrice.value
488
+ );
489
+
490
+ return Types.AssetAmount({
491
+ sign: true,
492
+ denomination: Types.AssetDenomination.Wei,
493
+ ref: Types.AssetReference.Delta,
494
+ value: owedAmount
495
+ });
496
+ }
497
+
498
+ function _owedWeiToHeldWei(
499
+ IDolomiteMargin dolomiteMargin,
500
+ Types.Wei memory owedWei,
501
+ uint256 heldMarketId,
502
+ uint256 owedMarketId,
503
+ uint32 expiry
504
+ )
505
+ private
506
+ view
507
+ returns (Types.AssetAmount memory)
508
+ {
509
+ (
510
+ Monetary.Price memory heldPrice,
511
+ Monetary.Price memory owedPrice
512
+ ) = _getSpreadAdjustedPrices(
513
+ dolomiteMargin,
514
+ heldMarketId,
515
+ owedMarketId,
516
+ expiry
517
+ );
518
+
519
+ uint256 heldAmount = Math.getPartial(
520
+ owedWei.value,
521
+ owedPrice.value,
522
+ heldPrice.value
523
+ );
524
+
525
+ return Types.AssetAmount({
526
+ sign: false,
527
+ denomination: Types.AssetDenomination.Wei,
528
+ ref: Types.AssetReference.Delta,
529
+ value: heldAmount
530
+ });
531
+ }
532
+ }
@@ -0,0 +1,118 @@
1
+ pragma solidity ^0.5.16;
2
+
3
+ import "@openzeppelin/contracts/math/SafeMath.sol";
4
+
5
+
6
+ contract UniswapV2ERC20 {
7
+ using SafeMath for uint;
8
+
9
+ // solium-disable-next-line uppercase
10
+ string public constant name = "Uniswap V2";
11
+ // solium-disable-next-line uppercase
12
+ string public constant symbol = "UNI-V2";
13
+ // solium-disable-next-line uppercase
14
+ uint8 public constant decimals = 18;
15
+ uint public totalSupply;
16
+ mapping(address => uint) public balanceOf;
17
+ mapping(address => mapping(address => uint)) public allowance;
18
+
19
+ bytes32 public DOMAIN_SEPARATOR;
20
+ // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
21
+ bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
22
+ mapping(address => uint) public nonces;
23
+
24
+ event Approval(address indexed owner, address indexed spender, uint value);
25
+ event Transfer(address indexed from, address indexed to, uint value);
26
+
27
+ constructor() public {
28
+ uint chainId;
29
+ // solium-disable-next-line security/no-inline-assembly
30
+ assembly {
31
+ chainId := chainid()
32
+ }
33
+ DOMAIN_SEPARATOR = keccak256(
34
+ abi.encode(
35
+ keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
36
+ keccak256(bytes(name)),
37
+ keccak256(bytes("1")),
38
+ chainId,
39
+ address(this)
40
+ )
41
+ );
42
+ }
43
+
44
+ function approve(address spender, uint value) external returns (bool) {
45
+ _approve(msg.sender, spender, value);
46
+ return true;
47
+ }
48
+
49
+ function transfer(address to, uint value) external returns (bool) {
50
+ _transfer(msg.sender, to, value);
51
+ return true;
52
+ }
53
+
54
+ function transferFrom(address from, address to, uint value) external returns (bool) {
55
+ if (allowance[from][msg.sender] != uint(-1)) {
56
+ allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
57
+ }
58
+ _transfer(from, to, value);
59
+ return true;
60
+ }
61
+
62
+ function permit(
63
+ address owner,
64
+ address spender,
65
+ uint value,
66
+ uint deadline,
67
+ uint8 v,
68
+ bytes32 r,
69
+ bytes32 s
70
+ )
71
+ external
72
+ {
73
+ require(deadline >= block.timestamp, "UniswapV2: EXPIRED");
74
+ bytes32 digest = keccak256(
75
+ abi.encodePacked(
76
+ "\x19\x01",
77
+ DOMAIN_SEPARATOR,
78
+ keccak256(
79
+ abi.encode(
80
+ PERMIT_TYPEHASH,
81
+ owner,
82
+ spender,
83
+ value,
84
+ nonces[owner]++,
85
+ deadline
86
+ )
87
+ )
88
+ )
89
+ );
90
+ // solium-disable-next-line arg-overflow
91
+ address recoveredAddress = ecrecover(digest, v, r, s);
92
+ require(recoveredAddress != address(0) && recoveredAddress == owner, "UniswapV2: INVALID_SIGNATURE");
93
+ _approve(owner, spender, value);
94
+ }
95
+
96
+ function _mint(address to, uint value) internal {
97
+ totalSupply = totalSupply.add(value);
98
+ balanceOf[to] = balanceOf[to].add(value);
99
+ emit Transfer(address(0), to, value);
100
+ }
101
+
102
+ function _burn(address from, uint value) internal {
103
+ balanceOf[from] = balanceOf[from].sub(value);
104
+ totalSupply = totalSupply.sub(value);
105
+ emit Transfer(from, address(0), value);
106
+ }
107
+
108
+ function _approve(address owner, address spender, uint value) private {
109
+ allowance[owner][spender] = value;
110
+ emit Approval(owner, spender, value);
111
+ }
112
+
113
+ function _transfer(address from, address to, uint value) private {
114
+ balanceOf[from] = balanceOf[from].sub(value);
115
+ balanceOf[to] = balanceOf[to].add(value);
116
+ emit Transfer(from, to, value);
117
+ }
118
+ }
@@ -0,0 +1,67 @@
1
+ pragma solidity ^0.5.16;
2
+
3
+ import "./interfaces/IUniswapV2Factory.sol";
4
+
5
+ import "./UniswapV2Pair.sol";
6
+
7
+
8
+ contract UniswapV2Factory is IUniswapV2Factory {
9
+ address public feeTo;
10
+ address public feeToSetter;
11
+
12
+ mapping(address => mapping(address => address)) public getPair;
13
+ address[] public allPairs;
14
+
15
+ event PairCreated(address indexed token0, address indexed token1, address pair, uint);
16
+
17
+ constructor(address _feeToSetter) public {
18
+ feeToSetter = _feeToSetter;
19
+ }
20
+
21
+ function allPairsLength() external view returns (uint) {
22
+ return allPairs.length;
23
+ }
24
+
25
+ function createPair(address tokenA, address tokenB) external returns (address pair) {
26
+ require(tokenA != tokenB, "UniswapV2: IDENTICAL_ADDRESSES");
27
+ (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
28
+ require(token0 != address(0), "UniswapV2: ZERO_ADDRESS");
29
+ require(getPair[token0][token1] == address(0), "UniswapV2: PAIR_EXISTS"); // single check is sufficient
30
+ bytes memory bytecode = type(UniswapV2Pair).creationCode;
31
+ bytes32 salt = keccak256(abi.encodePacked(token0, token1));
32
+ // solium-disable security/no-inline-assembly
33
+ assembly {
34
+ pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
35
+ }
36
+ UniswapV2Pair(pair).initialize(token0, token1);
37
+ getPair[token0][token1] = pair;
38
+ getPair[token1][token0] = pair; // populate mapping in the reverse direction
39
+ allPairs.push(pair);
40
+ emit PairCreated(
41
+ token0,
42
+ token1,
43
+ pair,
44
+ allPairs.length
45
+ );
46
+ }
47
+
48
+ function setFeeTo(address _feeTo) external {
49
+ require(msg.sender == feeToSetter, "UniswapV2: FORBIDDEN");
50
+ feeTo = _feeTo;
51
+ }
52
+
53
+ function setFeeToSetter(address _feeToSetter) external {
54
+ require(msg.sender == feeToSetter, "UniswapV2: FORBIDDEN");
55
+ feeToSetter = _feeToSetter;
56
+ }
57
+
58
+ function getPairInitCodeHash() external pure returns (bytes32) {
59
+ // This function is not in the IUniswapV2Factory interface because it does not exist in production
60
+ return keccak256(getPairInitCode());
61
+ }
62
+
63
+ function getPairInitCode() public pure returns (bytes memory) {
64
+ // This function is not in the IUniswapV2Factory interface because it does not exist in production
65
+ return type(UniswapV2Pair).creationCode;
66
+ }
67
+ }