@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,323 @@
1
+ /*
2
+
3
+ Copyright 2021 Dolomite.
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.0;
20
+
21
+ import "@openzeppelin/contracts/math/SafeMath.sol";
22
+
23
+ import "../../protocol/lib/Require.sol";
24
+
25
+ import "../uniswap-v2/interfaces/IUniswapV2Pair.sol";
26
+
27
+ import "../interfaces/IDolomiteAmmFactory.sol";
28
+ import "../interfaces/IDolomiteAmmPair.sol";
29
+
30
+
31
+ library DolomiteAmmLibrary {
32
+ using SafeMath for uint;
33
+
34
+ bytes32 private constant FILE = "DolomiteAmmLibrary";
35
+ bytes32 private constant PAIR_INIT_CODE_HASH = 0x752b18f9c5dbceeac7339c1e7d27b76a85637748e21b577cfb0b8768a8fd5ce7;
36
+
37
+ function getPairInitCodeHash() internal pure returns (bytes32) {
38
+ return PAIR_INIT_CODE_HASH;
39
+ }
40
+
41
+ function getPools(
42
+ address factory,
43
+ address[] memory path
44
+ ) internal pure returns (address[] memory) {
45
+ return getPools(factory, PAIR_INIT_CODE_HASH, path);
46
+ }
47
+
48
+ function getPools(
49
+ address factory,
50
+ bytes32 initCodeHash,
51
+ address[] memory path
52
+ ) internal pure returns (address[] memory) {
53
+ Require.that(
54
+ path.length >= 2,
55
+ FILE,
56
+ "invalid path length"
57
+ );
58
+
59
+ address[] memory pools = new address[](path.length - 1);
60
+ for (uint i = 0; i < path.length - 1; i++) {
61
+ pools[i] = pairFor(
62
+ factory,
63
+ path[i],
64
+ path[i + 1],
65
+ initCodeHash
66
+ );
67
+ }
68
+ return pools;
69
+ }
70
+
71
+ // returns sorted token addresses, used to handle return values from pairs sorted in this order
72
+ function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
73
+ Require.that(
74
+ tokenA != tokenB,
75
+ FILE,
76
+ "identical addresses"
77
+ );
78
+ (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
79
+ Require.that(
80
+ token0 != address(0),
81
+ FILE,
82
+ "zero address"
83
+ );
84
+ }
85
+
86
+ // calculates the CREATE2 address for a pair without making any external calls
87
+ function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {
88
+ return pairFor(
89
+ factory,
90
+ tokenA,
91
+ tokenB,
92
+ PAIR_INIT_CODE_HASH
93
+ );
94
+ }
95
+
96
+ function pairFor(
97
+ address factory,
98
+ address tokenA,
99
+ address tokenB,
100
+ bytes32 initCodeHash
101
+ ) internal pure returns (address pair) {
102
+ (address token0, address token1) = sortTokens(tokenA, tokenB);
103
+ pair = address(
104
+ uint(
105
+ keccak256(
106
+ abi.encodePacked(
107
+ hex"ff",
108
+ factory,
109
+ keccak256(abi.encodePacked(token0, token1)),
110
+ initCodeHash
111
+ )
112
+ )
113
+ )
114
+ );
115
+ }
116
+
117
+ // fetches and sorts the reserves for a pair
118
+ function getReservesWei(
119
+ address factory,
120
+ address tokenA,
121
+ address tokenB
122
+ ) internal view returns (uint reserveA, uint reserveB) {
123
+ return getReservesWei(
124
+ factory,
125
+ PAIR_INIT_CODE_HASH,
126
+ tokenA,
127
+ tokenB
128
+ );
129
+ }
130
+
131
+ function getReserves(
132
+ address factory,
133
+ bytes32 initCodeHash,
134
+ address tokenA,
135
+ address tokenB
136
+ ) internal view returns (uint reserveA, uint reserveB) {
137
+ (address token0,) = sortTokens(tokenA, tokenB);
138
+ (uint reserve0, uint reserve1,) = IUniswapV2Pair(
139
+ pairFor(
140
+ factory,
141
+ tokenA,
142
+ tokenB,
143
+ initCodeHash
144
+ )
145
+ ).getReserves();
146
+ (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
147
+ }
148
+
149
+ function getReservesWei(
150
+ address factory,
151
+ bytes32 initCodeHash,
152
+ address tokenA,
153
+ address tokenB
154
+ ) internal view returns (uint reserveA, uint reserveB) {
155
+ (address token0,) = sortTokens(tokenA, tokenB);
156
+ (uint reserve0, uint reserve1,) = IDolomiteAmmPair(
157
+ pairFor(
158
+ factory,
159
+ tokenA,
160
+ tokenB,
161
+ initCodeHash
162
+ )
163
+ ).getReservesWei();
164
+ (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
165
+ }
166
+
167
+ // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset
168
+ function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) {
169
+ Require.that(
170
+ amountA > 0,
171
+ FILE,
172
+ "insufficient amount"
173
+ );
174
+ Require.that(
175
+ reserveA > 0 && reserveB > 0,
176
+ FILE,
177
+ "insufficient liquidity"
178
+ );
179
+ amountB = amountA.mul(reserveB) / reserveA;
180
+ }
181
+
182
+ // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
183
+ function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
184
+ Require.that(
185
+ amountIn > 0,
186
+ FILE,
187
+ "insufficient input amount"
188
+ );
189
+ Require.that(
190
+ reserveIn > 0 && reserveOut > 0,
191
+ FILE,
192
+ "insufficient liquidity"
193
+ );
194
+ uint amountInWithFee = amountIn.mul(997);
195
+ uint numerator = amountInWithFee.mul(reserveOut);
196
+ uint denominator = reserveIn.mul(1000).add(amountInWithFee);
197
+ amountOut = numerator / denominator;
198
+ }
199
+
200
+ // given an output amount of an asset and pair reserves, returns a required input amount of the other asset
201
+ function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) {
202
+ Require.that(
203
+ amountOut > 0,
204
+ FILE,
205
+ "insufficient output amount"
206
+ );
207
+ Require.that(
208
+ reserveIn > 0 && reserveOut > 0,
209
+ FILE,
210
+ "insufficient liquidity"
211
+ );
212
+ uint numerator = reserveIn.mul(amountOut).mul(1000);
213
+ uint denominator = reserveOut.sub(amountOut).mul(997);
214
+ // reverts from the 'sub'
215
+ amountIn = numerator.div(denominator).add(1);
216
+ }
217
+
218
+ // performs chained getAmountOut calculations on any number of pairs
219
+ function getAmountsOutWei(
220
+ address factory,
221
+ uint amountIn,
222
+ address[] memory path
223
+ ) internal view returns (uint[] memory amounts) {
224
+ Require.that(
225
+ path.length >= 2,
226
+ FILE,
227
+ "invalid path"
228
+ );
229
+ amounts = new uint[](path.length);
230
+ amounts[0] = amountIn;
231
+ for (uint i; i < path.length - 1; i++) {
232
+ (uint reserveIn, uint reserveOut) = getReservesWei(factory, path[i], path[i + 1]);
233
+ amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
234
+ }
235
+ }
236
+
237
+ // performs chained getAmountOut calculations on any number of pairs
238
+ function getAmountsOutWei(
239
+ address factory,
240
+ bytes32 initCodeHash,
241
+ uint amountIn,
242
+ address[] memory path
243
+ ) internal view returns (uint[] memory amounts) {
244
+ Require.that(
245
+ path.length >= 2,
246
+ FILE,
247
+ "invalid path"
248
+ );
249
+ amounts = new uint[](path.length);
250
+ amounts[0] = amountIn;
251
+ for (uint i; i < path.length - 1; i++) {
252
+ (uint reserveIn, uint reserveOut) = getReservesWei(
253
+ factory,
254
+ initCodeHash,
255
+ path[i],
256
+ path[i + 1]
257
+ );
258
+ amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
259
+ }
260
+ }
261
+
262
+ function getAmountsInWei(
263
+ address factory,
264
+ bytes32 initCodeHash,
265
+ uint amountOut,
266
+ address[] memory path
267
+ ) internal view returns (uint[] memory amounts) {
268
+ Require.that(
269
+ path.length >= 2,
270
+ FILE,
271
+ "invalid path"
272
+ );
273
+ amounts = new uint[](path.length);
274
+ amounts[amounts.length - 1] = amountOut;
275
+ for (uint i = path.length - 1; i > 0; i--) {
276
+ (uint reserveIn, uint reserveOut) = getReservesWei(
277
+ factory,
278
+ initCodeHash,
279
+ path[i - 1],
280
+ path[i]
281
+ );
282
+ amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
283
+ }
284
+ }
285
+
286
+ function getAmountsIn(
287
+ address factory,
288
+ bytes32 initCodeHash,
289
+ uint amountOut,
290
+ address[] memory path
291
+ ) internal view returns (uint[] memory amounts) {
292
+ Require.that(
293
+ path.length >= 2,
294
+ FILE,
295
+ "invalid path"
296
+ );
297
+ amounts = new uint[](path.length);
298
+ amounts[amounts.length - 1] = amountOut;
299
+ for (uint i = path.length - 1; i > 0; i--) {
300
+ (uint reserveIn, uint reserveOut) = getReserves(
301
+ factory,
302
+ initCodeHash,
303
+ path[i - 1],
304
+ path[i]
305
+ );
306
+ amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
307
+ }
308
+ }
309
+
310
+ // performs chained getAmountIn calculations on any number of pairs
311
+ function getAmountsInWei(
312
+ address factory,
313
+ uint amountOut,
314
+ address[] memory path
315
+ ) internal view returns (uint[] memory amounts) {
316
+ return getAmountsInWei(
317
+ factory,
318
+ PAIR_INIT_CODE_HASH,
319
+ amountOut,
320
+ path
321
+ );
322
+ }
323
+ }
@@ -0,0 +1,120 @@
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 { Require } from "../../protocol/lib/Require.sol";
23
+
24
+
25
+ /**
26
+ * @title TypedSignature
27
+ * @author dYdX
28
+ *
29
+ * Library to unparse typed signatures
30
+ */
31
+ library TypedSignature {
32
+
33
+ // ============ Constants ============
34
+
35
+ bytes32 constant private FILE = "TypedSignature";
36
+
37
+ // prepended message with the length of the signed hash in decimal
38
+ bytes constant private PREPEND_DEC = "\x19Ethereum Signed Message:\n32";
39
+
40
+ // prepended message with the length of the signed hash in hexadecimal
41
+ bytes constant private PREPEND_HEX = "\x19Ethereum Signed Message:\n\x20";
42
+
43
+ // Number of bytes in a typed signature
44
+ uint256 constant private NUM_SIGNATURE_BYTES = 66;
45
+
46
+ // ============ Enums ============
47
+
48
+ // Different RPC providers may implement signing methods differently, so we allow different
49
+ // signature types depending on the string prepended to a hash before it was signed.
50
+ enum SignatureType {
51
+ NoPrepend, // No string was prepended.
52
+ Decimal, // PREPEND_DEC was prepended.
53
+ Hexadecimal, // PREPEND_HEX was prepended.
54
+ Invalid // Not a valid type. Used for bound-checking.
55
+ }
56
+
57
+ // ============ Functions ============
58
+
59
+ /**
60
+ * Gives the address of the signer of a hash. Also allows for the commonly prepended string of
61
+ * '\x19Ethereum Signed Message:\n' + message.length
62
+ *
63
+ * @param hash Hash that was signed (does not include prepended message)
64
+ * @param signatureWithType Type and ECDSA signature with structure: {32:r}{32:s}{1:v}{1:type}
65
+ * @return address of the signer of the hash
66
+ */
67
+ function recover(
68
+ bytes32 hash,
69
+ bytes memory signatureWithType
70
+ )
71
+ internal
72
+ pure
73
+ returns (address)
74
+ {
75
+ Require.that(
76
+ signatureWithType.length == NUM_SIGNATURE_BYTES,
77
+ FILE,
78
+ "Invalid signature length"
79
+ );
80
+
81
+ bytes32 r;
82
+ bytes32 s;
83
+ uint8 v;
84
+ uint8 rawSigType;
85
+
86
+ /* solium-disable-next-line security/no-inline-assembly */
87
+ assembly {
88
+ r := mload(add(signatureWithType, 0x20))
89
+ s := mload(add(signatureWithType, 0x40))
90
+ let lastSlot := mload(add(signatureWithType, 0x60))
91
+ v := byte(0, lastSlot)
92
+ rawSigType := byte(1, lastSlot)
93
+ }
94
+
95
+ Require.that(
96
+ rawSigType < uint8(SignatureType.Invalid),
97
+ FILE,
98
+ "Invalid signature type"
99
+ );
100
+
101
+ SignatureType sigType = SignatureType(rawSigType);
102
+
103
+ bytes32 signedHash;
104
+ if (sigType == SignatureType.NoPrepend) {
105
+ signedHash = hash;
106
+ } else if (sigType == SignatureType.Decimal) {
107
+ signedHash = keccak256(abi.encodePacked(PREPEND_DEC, hash));
108
+ } else {
109
+ assert(sigType == SignatureType.Hexadecimal);
110
+ signedHash = keccak256(abi.encodePacked(PREPEND_HEX, hash));
111
+ }
112
+
113
+ return ecrecover(
114
+ signedHash,
115
+ v,
116
+ r,
117
+ s
118
+ );
119
+ }
120
+ }
@@ -0,0 +1,22 @@
1
+ pragma solidity ^0.5.16;
2
+
3
+ // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
4
+
5
+ // range: [0, 2**112 - 1]
6
+ // resolution: 1 / 2**112
7
+
8
+
9
+ library UQ112x112 {
10
+ uint224 constant Q112 = 2 ** 112;
11
+
12
+ // encode a uint112 as a UQ112x112
13
+ function encode(uint112 y) internal pure returns (uint224 z) {
14
+ // never overflows
15
+ z = uint224(y) * Q112;
16
+ }
17
+
18
+ // divide a UQ112x112 by a uint112, returning a UQ112x112
19
+ function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
20
+ z = x / uint224(y);
21
+ }
22
+ }
@@ -0,0 +1,206 @@
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 { MultiSig } from "./MultiSig.sol";
23
+
24
+
25
+ /**
26
+ * @title DelayedMultiSig
27
+ * @author dYdX
28
+ *
29
+ * Multi-Signature Wallet with delay in execution.
30
+ * Allows multiple parties to execute a transaction after a time lock has passed.
31
+ * Adapted from Amir Bandeali's MultiSigWalletWithTimeLock contract.
32
+
33
+ * Logic Changes:
34
+ * - Only owners can execute transactions
35
+ * - Require that each transaction succeeds
36
+ * - Added function to execute multiple transactions within the same Ethereum transaction
37
+ */
38
+ contract DelayedMultiSig is
39
+ MultiSig
40
+ {
41
+ // ============ Events ============
42
+
43
+ event ConfirmationTimeSet(uint256 indexed transactionId, uint256 confirmationTime);
44
+ event TimeLockChange(uint32 secondsTimeLocked);
45
+
46
+ // ============ Storage ============
47
+
48
+ uint32 public secondsTimeLocked;
49
+ mapping (uint256 => uint256) public confirmationTimes;
50
+
51
+ // ============ Modifiers ============
52
+
53
+ modifier notFullyConfirmed(
54
+ uint256 transactionId
55
+ ) {
56
+ require(
57
+ !isConfirmed(transactionId),
58
+ "TX_FULLY_CONFIRMED"
59
+ );
60
+ _;
61
+ }
62
+
63
+ modifier fullyConfirmed(
64
+ uint256 transactionId
65
+ ) {
66
+ require(
67
+ isConfirmed(transactionId),
68
+ "TX_NOT_FULLY_CONFIRMED"
69
+ );
70
+ _;
71
+ }
72
+
73
+ modifier pastTimeLock(
74
+ uint256 transactionId
75
+ ) {
76
+ require(
77
+ block.timestamp >= confirmationTimes[transactionId] + secondsTimeLocked,
78
+ "TIME_LOCK_INCOMPLETE"
79
+ );
80
+ _;
81
+ }
82
+
83
+ // ============ Constructor ============
84
+
85
+ /**
86
+ * Contract constructor sets initial owners, required number of confirmations, and time lock.
87
+ *
88
+ * @param _owners List of initial owners.
89
+ * @param _required Number of required confirmations.
90
+ * @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it
91
+ * becomes executable, in seconds.
92
+ */
93
+ constructor (
94
+ address[] memory _owners,
95
+ uint256 _required,
96
+ uint32 _secondsTimeLocked
97
+ )
98
+ public
99
+ MultiSig(_owners, _required)
100
+ {
101
+ secondsTimeLocked = _secondsTimeLocked;
102
+ }
103
+
104
+ // ============ Wallet-Only Functions ============
105
+
106
+ /**
107
+ * Changes the duration of the time lock for transactions.
108
+ *
109
+ * @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it
110
+ * becomes executable, in seconds.
111
+ */
112
+ function changeTimeLock(
113
+ uint32 _secondsTimeLocked
114
+ )
115
+ public
116
+ onlyWallet
117
+ {
118
+ secondsTimeLocked = _secondsTimeLocked;
119
+ emit TimeLockChange(_secondsTimeLocked);
120
+ }
121
+
122
+ // ============ Admin Functions ============
123
+
124
+ /**
125
+ * Allows an owner to confirm a transaction.
126
+ * Overrides the function in MultiSig.
127
+ *
128
+ * @param transactionId Transaction ID.
129
+ */
130
+ function confirmTransaction(
131
+ uint256 transactionId
132
+ )
133
+ public
134
+ ownerExists(msg.sender)
135
+ transactionExists(transactionId)
136
+ notConfirmed(transactionId, msg.sender)
137
+ notFullyConfirmed(transactionId)
138
+ {
139
+ confirmations[transactionId][msg.sender] = true;
140
+ emit Confirmation(msg.sender, transactionId);
141
+ if (isConfirmed(transactionId)) {
142
+ setConfirmationTime(transactionId, block.timestamp);
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Allows an owner to execute a confirmed transaction.
148
+ * Overrides the function in MultiSig.
149
+ *
150
+ * @param transactionId Transaction ID.
151
+ */
152
+ function executeTransaction(
153
+ uint256 transactionId
154
+ )
155
+ public
156
+ ownerExists(msg.sender)
157
+ notExecuted(transactionId)
158
+ fullyConfirmed(transactionId)
159
+ pastTimeLock(transactionId)
160
+ {
161
+ Transaction storage txn = transactions[transactionId];
162
+ txn.executed = true;
163
+ bool success = externalCall(
164
+ txn.destination,
165
+ txn.value,
166
+ txn.data.length,
167
+ txn.data
168
+ );
169
+ require(
170
+ success,
171
+ "TX_REVERTED"
172
+ );
173
+ emit Execution(transactionId);
174
+ }
175
+
176
+ /**
177
+ * Allows an owner to execute multiple confirmed transactions.
178
+ *
179
+ * @param transactionIds List of transaction IDs.
180
+ */
181
+ function executeMultipleTransactions(
182
+ uint256[] memory transactionIds
183
+ )
184
+ public
185
+ ownerExists(msg.sender)
186
+ {
187
+ for (uint256 i = 0; i < transactionIds.length; i++) {
188
+ executeTransaction(transactionIds[i]);
189
+ }
190
+ }
191
+
192
+ // ============ Helper Functions ============
193
+
194
+ /**
195
+ * Sets the time of when a submission first passed.
196
+ */
197
+ function setConfirmationTime(
198
+ uint256 transactionId,
199
+ uint256 confirmationTime
200
+ )
201
+ internal
202
+ {
203
+ confirmationTimes[transactionId] = confirmationTime;
204
+ emit ConfirmationTimeSet(transactionId, confirmationTime);
205
+ }
206
+ }