@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.
- package/build/contracts/Account.json +11 -11
- package/build/contracts/Actions.json +11 -11
- package/build/contracts/Address.json +1 -1
- package/build/contracts/Admin.json +23 -23
- package/build/contracts/AdminImpl.json +35 -307
- package/build/contracts/AdvancedMath.json +7 -7
- package/build/contracts/AmmRebalancerProxy.json +577 -621
- package/build/contracts/AmmRebalancerProxyV1.json +78 -32
- package/build/contracts/Babylonian.json +1 -1
- package/build/contracts/Bits.json +9 -9
- package/build/contracts/Cache.json +13 -13
- package/build/contracts/ChainlinkPriceOracleV1.json +16 -16
- package/build/contracts/Context.json +1 -1
- package/build/contracts/CustomTestToken.json +9 -9
- package/build/contracts/Decimal.json +9 -9
- package/build/contracts/DelayedMultiSig.json +9 -9
- package/build/contracts/DolomiteAmmERC20.json +11 -11
- package/build/contracts/DolomiteAmmFactory.json +14 -52
- package/build/contracts/DolomiteAmmLibrary.json +24 -24
- package/build/contracts/DolomiteAmmPair.json +27 -27
- package/build/contracts/DolomiteAmmRouterProxy.json +30 -363
- package/build/contracts/DolomiteMargin.json +21 -67
- package/build/contracts/DoubleExponentInterestSetter.json +15 -21
- package/build/contracts/EnumerableSet.json +7 -7
- package/build/contracts/ErroringOmiseToken.json +9 -9
- package/build/contracts/ErroringToken.json +10 -10
- package/build/contracts/Events.json +17 -17
- package/build/contracts/ExcessivelySafeCall.json +35 -35
- package/build/contracts/Exchange.json +15 -15
- package/build/contracts/Expiry.json +36 -36
- package/build/contracts/Getters.json +33 -33
- package/build/contracts/IAutoTrader.json +9 -9
- package/build/contracts/ICallee.json +7 -7
- package/build/contracts/IChainlinkAggregator.json +5 -5
- package/build/contracts/IDolomiteAmmERC20.json +5 -5
- package/build/contracts/IDolomiteAmmFactory.json +9 -9
- package/build/contracts/IDolomiteAmmPair.json +9 -9
- package/build/contracts/IDolomiteMargin.json +23 -23
- package/build/contracts/IERC20.json +1 -1
- package/build/contracts/IERC20Detailed.json +5 -5
- package/build/contracts/IExchangeWrapper.json +5 -5
- package/build/contracts/IExpiry.json +9 -9
- package/build/contracts/IInterestSetter.json +7 -7
- package/build/contracts/ILiquidationCallback.json +7 -7
- package/build/contracts/IMakerOracle.json +5 -5
- package/build/contracts/IOasisDex.json +5 -5
- package/build/contracts/IPriceOracle.json +7 -7
- package/build/contracts/IRecyclable.json +9 -9
- package/build/contracts/ITransferProxy.json +5 -5
- package/build/contracts/IUniswapV2Callee.json +5 -5
- package/build/contracts/IUniswapV2Factory.json +5 -5
- package/build/contracts/IUniswapV2Pair.json +5 -5
- package/build/contracts/IUniswapV2Router.json +5 -5
- package/build/contracts/IWETH.json +5 -5
- package/build/contracts/Interest.json +15 -15
- package/build/contracts/LiquidateOrVaporizeImpl.json +32 -83
- package/build/contracts/LiquidatorProxyHelper.json +23 -23
- package/build/contracts/LiquidatorProxyV1.json +30 -36
- package/build/contracts/LiquidatorProxyV1WithAmm.json +49 -105
- package/build/contracts/Math.json +1 -1
- package/build/contracts/Migrations.json +8 -14
- package/build/contracts/Monetary.json +7 -7
- package/build/contracts/MultiCall.json +8 -14
- package/build/contracts/MultiSig.json +7 -7
- package/build/contracts/OmiseToken.json +8 -8
- package/build/contracts/OnlyDolomiteMargin.json +11 -11
- package/build/contracts/Operation.json +15 -15
- package/build/contracts/OperationImpl.json +39 -47
- package/build/contracts/Ownable.json +1 -1
- package/build/contracts/PartiallyDelayedMultiSig.json +9 -9
- package/build/contracts/PayableProxy.json +17 -23
- package/build/contracts/Permission.json +11 -11
- package/build/contracts/PolynomialInterestSetter.json +13 -13
- package/build/contracts/RecyclableTokenProxy.json +25 -25
- package/build/contracts/ReentrancyGuard.json +1 -1
- package/build/contracts/Require.json +7 -7
- package/build/contracts/SafeERC20.json +1 -1
- package/build/contracts/SafeETH.json +7 -7
- package/build/contracts/SafeLiquidationCallback.json +17 -17
- package/build/contracts/SafeMath.json +1 -1
- package/build/contracts/SignedOperationProxy.json +21 -104
- package/build/contracts/SimpleFeeOwner.json +18 -63
- package/build/contracts/State.json +9 -9
- package/build/contracts/Storage.json +37 -37
- package/build/contracts/TestAmmRebalancerProxy.json +32 -58
- package/build/contracts/TestAutoTrader.json +22 -22
- package/build/contracts/TestBtcUsdChainlinkAggregator.json +10 -10
- package/build/contracts/TestCallee.json +19 -19
- package/build/contracts/TestChainlinkPriceOracleV1.json +10 -94
- package/build/contracts/TestCounter.json +7 -7
- package/build/contracts/TestDaiUsdChainlinkAggregator.json +11 -11
- package/build/contracts/TestDolomiteMargin.json +22 -22
- package/build/contracts/TestDoubleExponentInterestSetter.json +10 -10
- package/build/contracts/TestEthUsdChainlinkAggregator.json +11 -11
- package/build/contracts/TestExchangeWrapper.json +28 -28
- package/build/contracts/TestInterestSetter.json +13 -13
- package/build/contracts/TestLib.json +22 -22
- package/build/contracts/TestLinkUsdChainlinkAggregator.json +11 -11
- package/build/contracts/TestLiquidateCallback.json +719 -719
- package/build/contracts/TestLiquidationCallback.json +13 -13
- package/build/contracts/TestLrcEthChainlinkAggregator.json +11 -11
- package/build/contracts/TestMakerOracle.json +10 -10
- package/build/contracts/TestMaticUsdChainlinkAggregator.json +10 -10
- package/build/contracts/TestOasisDex.json +12 -12
- package/build/contracts/TestOperationImpl.json +14 -14
- package/build/contracts/TestPolynomialInterestSetter.json +10 -10
- package/build/contracts/TestPriceAggregator.json +9 -9
- package/build/contracts/TestPriceOracle.json +13 -13
- package/build/contracts/TestRecyclableToken.json +9 -9
- package/build/contracts/TestSimpleCallee.json +15 -15
- package/build/contracts/TestToken.json +9 -9
- package/build/contracts/TestTrader.json +17 -17
- package/build/contracts/TestUniswapAmmRebalancerProxy.json +16 -16
- package/build/contracts/TestUsdcUsdChainlinkAggregator.json +11 -11
- package/build/contracts/TestWETH.json +9 -9
- package/build/contracts/Time.json +9 -9
- package/build/contracts/Token.json +9 -9
- package/build/contracts/TokenA.json +10 -10
- package/build/contracts/TokenB.json +10 -10
- package/build/contracts/TokenC.json +10 -10
- package/build/contracts/TokenD.json +10 -10
- package/build/contracts/TokenE.json +10 -10
- package/build/contracts/TokenF.json +10 -10
- package/build/contracts/TransferProxy.json +22 -28
- package/build/contracts/TypedSignature.json +9 -9
- package/build/contracts/Types.json +9 -9
- package/build/contracts/UQ112x112.json +7 -7
- package/build/contracts/UniswapV2ERC20.json +7 -7
- package/build/contracts/UniswapV2Factory.json +12 -12
- package/build/contracts/UniswapV2Library.json +20 -20
- package/build/contracts/UniswapV2Pair.json +17 -17
- package/build/contracts/UniswapV2Router02.json +16 -16
- package/build/contracts/WETH9.json +1 -1
- package/contracts/external/amm/DolomiteAmmERC20.sol +135 -0
- package/contracts/external/amm/DolomiteAmmFactory.sol +122 -0
- package/contracts/external/amm/DolomiteAmmPair.sol +573 -0
- package/contracts/external/amm/SimpleFeeOwner.sol +107 -0
- package/contracts/external/helpers/LiquidatorProxyHelper.sol +252 -0
- package/contracts/external/helpers/OnlyDolomiteMargin.sol +63 -0
- package/contracts/external/interestsetters/DoubleExponentInterestSetter.sol +212 -0
- package/contracts/external/interestsetters/PolynomialInterestSetter.sol +205 -0
- package/contracts/external/interfaces/IChainlinkAggregator.sol +33 -0
- package/contracts/external/interfaces/IDolomiteAmmERC20.sol +52 -0
- package/contracts/external/interfaces/IDolomiteAmmFactory.sol +42 -0
- package/contracts/external/interfaces/IDolomiteAmmPair.sol +116 -0
- package/contracts/external/interfaces/IExpiry.sol +70 -0
- package/contracts/external/interfaces/IMakerOracle.sol +52 -0
- package/contracts/external/interfaces/IOasisDex.sol +326 -0
- package/contracts/external/interfaces/ITransferProxy.sol +53 -0
- package/contracts/external/interfaces/IUniswapV2Router.sol +134 -0
- package/contracts/external/lib/AdvancedMath.sol +23 -0
- package/contracts/external/lib/DolomiteAmmLibrary.sol +323 -0
- package/contracts/external/lib/TypedSignature.sol +120 -0
- package/contracts/external/lib/UQ112x112.sol +22 -0
- package/contracts/external/multisig/DelayedMultiSig.sol +206 -0
- package/contracts/external/multisig/MultiSig.sol +571 -0
- package/contracts/external/multisig/PartiallyDelayedMultiSig.sol +174 -0
- package/contracts/external/oracles/ChainlinkPriceOracleV1.sol +197 -0
- package/contracts/external/oracles/TestChainlinkPriceOracleV1.sol +98 -0
- package/contracts/external/proxies/AmmRebalancerProxyV1.sol +465 -0
- package/contracts/external/proxies/DolomiteAmmRouterProxy.sol +877 -0
- package/contracts/external/proxies/LiquidatorProxyV1.sol +507 -0
- package/contracts/external/proxies/LiquidatorProxyV1WithAmm.sol +574 -0
- package/contracts/external/proxies/PayableProxy.sol +146 -0
- package/contracts/external/proxies/RecyclableTokenProxy.sol +463 -0
- package/contracts/external/proxies/SignedOperationProxy.sol +553 -0
- package/contracts/external/proxies/TransferProxy.sol +207 -0
- package/contracts/external/traders/Expiry.sol +532 -0
- package/contracts/external/uniswap-v2/UniswapV2ERC20.sol +118 -0
- package/contracts/external/uniswap-v2/UniswapV2Factory.sol +67 -0
- package/contracts/external/uniswap-v2/UniswapV2Pair.sol +283 -0
- package/contracts/external/uniswap-v2/UniswapV2Router02.sol +566 -0
- package/contracts/external/uniswap-v2/interfaces/IUniswapV2Callee.sol +13 -0
- package/contracts/external/uniswap-v2/interfaces/IUniswapV2Factory.sol +18 -0
- package/contracts/external/uniswap-v2/interfaces/IUniswapV2Pair.sol +67 -0
- package/contracts/external/uniswap-v2/interfaces/IWETH.sol +7 -0
- package/contracts/external/uniswap-v2/libraries/SafeETH.sol +29 -0
- package/contracts/external/uniswap-v2/libraries/UniswapV2Library.sol +117 -0
- package/contracts/external/utils/MultiCall.sol +95 -0
- package/contracts/protocol/impl/artifacts/OperationImpl.json +80 -0
- package/contracts/protocol/impl/artifacts/OperationImpl_metadata.json +193 -0
- package/dist/build/published_contracts/AdminImpl.json +2 -2
- package/dist/build/published_contracts/AmmRebalancerProxyV1.json +5 -0
- package/dist/build/published_contracts/ChainlinkPriceOracleV1.json +1 -1
- package/dist/build/published_contracts/DolomiteAmmFactory.json +1 -1
- package/dist/build/published_contracts/DolomiteAmmRouterProxy.json +1 -1
- package/dist/build/published_contracts/DoubleExponentInterestSetter.json +2 -2
- package/dist/build/published_contracts/Expiry.json +1 -1
- package/dist/build/published_contracts/LiquidatorProxyV1.json +1 -1
- package/dist/build/published_contracts/LiquidatorProxyV1WithAmm.json +1 -1
- package/dist/build/published_contracts/MultiCall.json +1 -1
- package/dist/build/published_contracts/PayableProxy.json +2 -2
- package/dist/build/published_contracts/SignedOperationProxy.json +2 -2
- package/dist/build/published_contracts/SimpleFeeOwner.json +1 -1
- package/dist/build/published_contracts/TestUniswapAmmRebalancerProxy.json +140 -0
- package/dist/build/published_contracts/TransferProxy.json +1 -1
- package/dist/src/lib/Contracts.d.ts +3 -1
- package/dist/src/lib/Contracts.js +7 -3
- package/dist/src/lib/Contracts.js.map +1 -1
- 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
|
+
}
|