Skip to content

Commit b25523f

Browse files
authored
Merge pull request #72 from OpenLeverageDev/borrowing
supported over collateralized borrowing
2 parents 8928c98 + 225ed25 commit b25523f

15 files changed

+376
-10
lines changed

contracts/ControllerInterface.sol

+21
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ contract ControllerStorage {
6262

6363
DexAggregatorInterface public dexAggregator;
6464

65+
//useless
6566
bool public suspend;
6667

6768
//useless
@@ -85,6 +86,11 @@ contract ControllerStorage {
8586

8687
bool public suspendAll;
8788

89+
//marketId=>isSuspend
90+
mapping(uint => bool) public borrowingSuspend;
91+
92+
address public opBorrowing;
93+
8894
event LPoolPairCreated(address token0, address pool0, address token1, address pool1, uint16 marketId, uint16 marginLimit, bytes dexData);
8995

9096
}
@@ -110,14 +116,25 @@ interface ControllerInterface {
110116

111117
function liquidateAllowed(uint marketId, address liquidator, uint liquidateAmount, bytes memory dexData) external;
112118

119+
//useless
113120
function marginTradeAllowed(uint marketId) external view returns (bool);
114121

122+
function marginTradeAllowedV2(uint marketId, address trader, bool longToken) external view returns (bool);
123+
115124
function closeTradeAllowed(uint marketId) external view returns (bool);
116125

117126
function updatePriceAllowed(uint marketId, address to) external;
118127

119128
function updateInterestAllowed(address payable sender) external;
120129

130+
function collBorrowAllowed(uint marketId, address borrower, bool collateralIndex) external view returns (bool);
131+
132+
function collRepayAllowed(uint marketId) external view returns (bool);
133+
134+
function collRedeemAllowed(uint marketId) external view returns (bool);
135+
136+
function collLiquidateAllowed(uint marketId) external view returns (bool);
137+
121138
/*** Admin Functions ***/
122139

123140
function setLPoolImplementation(address _lpoolImplementation) external;
@@ -130,14 +147,18 @@ interface ControllerInterface {
130147

131148
function setLPoolUnAllowed(address lpool, bool unAllowed) external;
132149

150+
//useless
133151
function setSuspend(bool suspend) external;
134152

135153
function setSuspendAll(bool suspend) external;
136154

137155
function setMarketSuspend(uint marketId, bool suspend) external;
138156

157+
function setBorrowingSuspend(uint marketId, bool suspend) external;
158+
139159
function setOleWethDexData(bytes memory _oleWethDexData) external;
140160

161+
function setOpBorrowing(address _opBorrowing) external;
141162

142163
}
143164

contracts/ControllerV1.sol

+58-6
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ contract ControllerV1 is DelegateInterface, Adminable, ControllerInterface, Cont
7676
lpoolPairs[token0][token1] = LPoolPair(address(pool0), address(pool1));
7777
lpoolPairs[token1][token0] = LPoolPair(address(pool0), address(pool1));
7878
uint16 marketId = (OpenLevInterface(openLev)).addMarket(LPoolInterface(address(pool0)), LPoolInterface(address(pool1)), pairVar.marginLimit, pairVar.dexData);
79+
if (opBorrowing != address(0)) {
80+
IOPBorrowing(opBorrowing).addMarket(marketId, address(pool0), address(pool1), pairVar.dexData);
81+
}
7982
emit LPoolPairCreated(pairVar.token0, address(pool0), pairVar.token1, address(pool1), marketId, pairVar.marginLimit, pairVar.dexData);
8083
}
8184

@@ -112,7 +115,7 @@ contract ControllerV1 is DelegateInterface, Adminable, ControllerInterface, Cont
112115
borrower;
113116
repayAmount;
114117
if (isEnd) {
115-
require(openLev == payer, "Operator not openLev");
118+
require(openLev == payer || opBorrowing == payer, "Operator not openLev");
116119
}
117120
}
118121

@@ -122,16 +125,23 @@ contract ControllerV1 is DelegateInterface, Adminable, ControllerInterface, Cont
122125
liquidateAmount;
123126
dexData;
124127
require(!marketSuspend[marketId], 'Market suspended');
125-
126128
}
127129

128130
function marginTradeAllowed(uint marketId) external view override onlyNotSuspended returns (bool){
129131
require(!marketSuspend[marketId], 'Market suspended');
130132
return true;
131133
}
132134

133-
function closeTradeAllowed(uint marketId) external view override returns (bool){
134-
require(!suspendAll, 'Suspended');
135+
function marginTradeAllowedV2(uint marketId, address trader, bool longToken) onlyNotSuspended external view override returns (bool){
136+
require(!marketSuspend[marketId], 'Market suspended');
137+
if (opBorrowing != address(0)) {
138+
require(IOPBorrowing(opBorrowing).activeCollaterals(trader, uint16(marketId), longToken) == 0, 'MBB');
139+
}
140+
return true;
141+
}
142+
143+
function closeTradeAllowed(uint marketId) external view override onlyNotSuspended returns (bool){
144+
marketId;
135145
return true;
136146
}
137147

@@ -146,6 +156,25 @@ contract ControllerV1 is DelegateInterface, Adminable, ControllerInterface, Cont
146156
}
147157

148158

159+
function collBorrowAllowed(uint marketId, address borrower, bool collateralIndex) external view override onlyNotSuspended onlyOpBorrowingNotSuspended(marketId) returns (bool){
160+
Types.Trade memory trade = IOpenLev(openLev).activeTrades(borrower, uint16(marketId), collateralIndex);
161+
require(trade.held == 0, 'BMB');
162+
return true;
163+
}
164+
165+
function collRepayAllowed(uint marketId) external view override onlyNotSuspended onlyOpBorrowingNotSuspended(marketId) returns (bool){
166+
return true;
167+
}
168+
169+
function collRedeemAllowed(uint marketId) external view override onlyNotSuspended onlyOpBorrowingNotSuspended(marketId) returns (bool){
170+
return true;
171+
}
172+
173+
function collLiquidateAllowed(uint marketId) external view override onlyNotSuspended onlyOpBorrowingNotSuspended(marketId) returns (bool){
174+
return true;
175+
}
176+
177+
149178
function setLPoolImplementation(address _lpoolImplementation) external override onlyAdmin {
150179
require(address(0) != _lpoolImplementation, '0x');
151180
lpoolImplementation = _lpoolImplementation;
@@ -185,24 +214,47 @@ contract ControllerV1 is DelegateInterface, Adminable, ControllerInterface, Cont
185214
marketSuspend[marketId] = suspend;
186215
}
187216

217+
function setBorrowingSuspend(uint marketId, bool suspend) external override onlyAdminOrDeveloper {
218+
borrowingSuspend[marketId] = suspend;
219+
}
220+
188221
function setOleWethDexData(bytes memory _oleWethDexData) external override onlyAdminOrDeveloper {
189222
oleWethDexData = _oleWethDexData;
190223
}
191224

225+
function setOpBorrowing(address _opBorrowing) external override onlyAdmin {
226+
opBorrowing = _opBorrowing;
227+
}
228+
192229
modifier onlyLPoolAllowed() {
193230
require(!lpoolUnAlloweds[msg.sender], "LPool paused");
194231
_;
195232
}
196233

197234
modifier onlyNotSuspended() {
198-
require(!suspend, 'Suspended');
199235
require(!suspendAll, 'Suspended all');
200236
_;
201237
}
202238

239+
modifier onlyOpBorrowingNotSuspended(uint marketId) {
240+
require(!borrowingSuspend[marketId], 'Suspended borrowing');
241+
_;
242+
}
203243
modifier onlyOpenLevOperator(address operator) {
204-
require(openLev == operator || openLev == address(0), "Operator not openLev");
244+
require((openLev == operator || openLev == address(0)) || (opBorrowing == operator), "Operator not openLev");
205245
_;
206246
}
247+
}
248+
249+
interface IOPBorrowing {
250+
251+
252+
function addMarket(uint16 marketId, address pool0, address pool1, bytes memory dexData) external;
253+
254+
function activeCollaterals(address borrower, uint16 marketId, bool collateralIndex) external view returns (uint);
255+
}
256+
257+
interface IOpenLev {
207258

259+
function activeTrades(address trader, uint16 marketId, bool longToken) external view returns (Types.Trade memory);
208260
}

contracts/OpenLevInterface.sol

+2
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,6 @@ interface OpenLevInterface {
174174

175175
function setRouter1inch(address _router1inch) external;
176176

177+
function getMarketSupportDexs(uint16 marketId) external view returns (uint32[] memory);
178+
177179
}

contracts/OpenLevV1.sol

+4-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ contract OpenLevV1 is DelegateInterface, Adminable, ReentrancyGuard, OpenLevInte
106106
{
107107
Types.Trade storage t = activeTrades[trader][marketId][longToken];
108108
OpenLevV1Lib.verifyTrade(vars, longToken, depositToken, deposit, borrow, dexData, addressConfig, t, msg.sender == opLimitOrder ? false : true);
109-
(ControllerInterface(addressConfig.controller)).marginTradeAllowed(marketId);
109+
(ControllerInterface(addressConfig.controller)).marginTradeAllowedV2(marketId, trader, longToken);
110110
if (dexData.isUniV2Class()) {
111111
updatePrice(address(vars.buyToken), address(vars.sellToken), calPriceDexData);
112112
}
@@ -462,6 +462,9 @@ contract OpenLevV1 is DelegateInterface, Adminable, ReentrancyGuard, OpenLevInte
462462
opLimitOrder = _opLimitOrder;
463463
}
464464

465+
function getMarketSupportDexs(uint16 marketId) external override view returns (uint32[] memory){
466+
return markets[marketId].dexs;
467+
}
465468

466469
function reduceInsurance(uint totalRepayment, uint remaining, uint16 marketId, bool longToken, address token, uint reserve) internal returns (uint maxCanRepayAmount) {
467470
Types.Market storage market = markets[marketId];

contracts/dex/DexAggregatorInterface.sol

+4
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@ interface DexAggregatorInterface {
2828
function updateV3Observation(address desToken, address quoteToken, bytes memory data) external;
2929

3030
function setDexInfo(uint8[] memory dexName, IUniswapV2Factory[] memory factoryAddr, uint16[] memory fees) external;
31+
32+
function getToken0Liquidity(address token0, address token1, bytes memory dexData) external view returns (uint);
33+
34+
function getPairLiquidity(address token0, address token1, bytes memory dexData) external view returns (uint token0Liq, uint token1Liq);
3135
}

contracts/dex/arbitrum/ArbitrumDexAggregatorV1.sol

+31
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ contract ArbitrumDexAggregatorV1 is DelegateInterface, Adminable, DexAggregatorI
2727

2828
mapping(uint8 => DexInfo) public dexInfo;
2929

30+
address public opBorrowing;
31+
3032
//v2 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f
3133
//v3 0x1f98431c8ad98523631ae4a59f267346ea31f984
3234
function initialize(
@@ -56,6 +58,11 @@ contract ArbitrumDexAggregatorV1 is DelegateInterface, Adminable, DexAggregatorI
5658
openLev = _openLev;
5759
}
5860

61+
function setOpBorrowing(address _opBorrowing) external onlyAdmin {
62+
require(address(0) != _opBorrowing, '0x');
63+
opBorrowing = _opBorrowing;
64+
}
65+
5966
/// @notice Sell tokens
6067
/// @dev Sell exact amount of token with tax applied
6168
/// @param buyToken Address of token transfer from Dex pair
@@ -250,4 +257,28 @@ contract ArbitrumDexAggregatorV1 is DelegateInterface, Adminable, DexAggregatorI
250257
increaseV3Observation(desToken, quoteToken, data.toFee());
251258
}
252259
}
260+
261+
function getToken0Liquidity(address token0, address token1, bytes memory dexData) external override view returns (uint){
262+
address pair;
263+
if (dexData.isUniV2Class()) {
264+
pair = getUniV2ClassPair(token0, token1, dexInfo[dexData.toDex()].factory);
265+
}
266+
else if (dexData.toDex() == DexData.DEX_UNIV3) {
267+
pair = address(getPool(token0, token1, dexData.toFee()));
268+
}
269+
require(pair != address(0), 'Ox');
270+
return IERC20(token0).balanceOf(pair);
271+
}
272+
273+
function getPairLiquidity(address token0, address token1, bytes memory dexData) external override view returns (uint token0Liq, uint token1Liq){
274+
address pair;
275+
if (dexData.isUniV2Class()) {
276+
pair = getUniV2ClassPair(token0, token1, dexInfo[dexData.toDex()].factory);
277+
}
278+
else if (dexData.toDex() == DexData.DEX_UNIV3) {
279+
pair = address(getPool(token0, token1, dexData.toFee()));
280+
}
281+
require(pair != address(0), 'Ox');
282+
return (IERC20(token0).balanceOf(pair), IERC20(token1).balanceOf(pair));
283+
}
253284
}

contracts/dex/bsc/BscDexAggregatorV1.sol

+19-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ contract BscDexAggregatorV1 is DelegateInterface, Adminable, DexAggregatorInterf
2525

2626
mapping(uint8 => DexInfo) public dexInfo;
2727

28+
address public opBorrowing;
29+
2830
//pancakeFactory: 0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73
2931
function initialize(
3032
IUniswapV2Factory _pancakeFactory,
@@ -54,6 +56,10 @@ contract BscDexAggregatorV1 is DelegateInterface, Adminable, DexAggregatorInterf
5456
openLev = _openLev;
5557
}
5658

59+
function setOpBorrowing(address _opBorrowing) external onlyAdmin {
60+
require(address(0) != _opBorrowing, '0x');
61+
opBorrowing = _opBorrowing;
62+
}
5763
/// @notice Sell tokens
5864
/// @dev Sell exact amount of token with tax applied
5965
/// @param buyToken Address of token transfer from Dex pair
@@ -175,7 +181,7 @@ contract BscDexAggregatorV1 is DelegateInterface, Adminable, DexAggregatorInterf
175181
/// @param data dex parameters
176182
/// @return If updated
177183
function updatePriceOracle(address desToken, address quoteToken, uint32 timeWindow, bytes memory data) external override returns (bool){
178-
require(msg.sender == openLev, "Only openLev can update price");
184+
require(msg.sender == openLev || msg.sender == opBorrowing, "Only openLev can update price");
179185
require(data.isUniV2Class(), "unsupported dex");
180186
address pair = getUniClassPair(desToken, quoteToken, dexInfo[data.toDex()].factory);
181187
V2PriceOracle memory priceOracle = uniV2PriceOracle[IUniswapV2Pair(pair)];
@@ -195,4 +201,16 @@ contract BscDexAggregatorV1 is DelegateInterface, Adminable, DexAggregatorInterf
195201
(desToken,quoteToken, data);
196202
revert("Not implemented");
197203
}
204+
205+
function getToken0Liquidity(address token0, address token1, bytes memory dexData) external override view returns (uint){
206+
require(dexData.isUniV2Class(), "unsupported dex");
207+
address pair = getUniClassPair(token0, token1, dexInfo[dexData.toDex()].factory);
208+
return IERC20(token0).balanceOf(pair);
209+
}
210+
211+
function getPairLiquidity(address token0, address token1, bytes memory dexData) external override view returns (uint token0Liq, uint token1Liq){
212+
require(dexData.isUniV2Class(), "unsupported dex");
213+
address pair = getUniClassPair(token0, token1, dexInfo[dexData.toDex()].factory);
214+
return (IERC20(token0).balanceOf(pair), IERC20(token1).balanceOf(pair));
215+
}
198216
}

contracts/dex/cronos/CronosDexAggregatorV1.sol

+18
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ contract CronosDexAggregatorV1 is DelegateInterface, Adminable, DexAggregatorInt
2525

2626
mapping(uint8 => DexInfo) public dexInfo;
2727

28+
address public opBorrowing;
29+
2830
function initialize(
2931
IUniswapV2Factory _vvsFactory,
3032
address _unusedFactory
@@ -52,6 +54,10 @@ contract CronosDexAggregatorV1 is DelegateInterface, Adminable, DexAggregatorInt
5254
openLev = _openLev;
5355
}
5456

57+
function setOpBorrowing(address _opBorrowing) external onlyAdmin {
58+
require(address(0) != _opBorrowing, '0x');
59+
opBorrowing = _opBorrowing;
60+
}
5561

5662
/// @notice Sell tokens
5763
/// @dev Sell exact amount of token with tax applied
@@ -194,4 +200,16 @@ contract CronosDexAggregatorV1 is DelegateInterface, Adminable, DexAggregatorInt
194200
(desToken,quoteToken, data);
195201
revert("Not implemented");
196202
}
203+
204+
function getToken0Liquidity(address token0, address token1, bytes memory dexData) external override view returns (uint){
205+
require(dexData.isUniV2Class(), "unsupported dex");
206+
address pair = getUniClassPair(token0, token1, dexInfo[dexData.toDex()].factory);
207+
return IERC20(token0).balanceOf(pair);
208+
}
209+
210+
function getPairLiquidity(address token0, address token1, bytes memory dexData) external override view returns (uint token0Liq, uint token1Liq){
211+
require(dexData.isUniV2Class(), "unsupported dex");
212+
address pair = getUniClassPair(token0, token1, dexInfo[dexData.toDex()].factory);
213+
return (IERC20(token0).balanceOf(pair), IERC20(token1).balanceOf(pair));
214+
}
197215
}

0 commit comments

Comments
 (0)