Skip to content

Commit a3ccff8

Browse files
authored
Merge pull request #80 from laminar-protocol/margin-multiple-spreads
MarginProtocol: add spreads per pool per token
2 parents 623b988 + 4a5cba2 commit a3ccff8

File tree

69 files changed

+2763
-1394
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+2763
-1394
lines changed

.soliumignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ contracts/Migrations.sol
33
contracts/libs/upgrades/Proxy.sol
44
contracts/libs/upgrades/ERC20DetailedUpgradable.sol
55
contracts/libs/upgrades/UpgradeAccessControl.sol
6-
contracts/interfaces/MarginLiquidityPoolInterface.sol
6+
contracts/impls/LiquidityPool.sol
7+
contracts/impls/synthetic/SyntheticLiquidityPool.sol
8+
contracts/impls/margin/MarginLiquidityPool.sol

artifacts/kovan/deployment.json

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
{
22
"baseToken": "0xbF7A7169562078c96f0eC1A8aFD6aE50f12e5A99",
33
"cToken": "0x0A1e4D0B5c71B955c0a5993023fc48bA6E380496",
4-
"moneyMarket": "0x5976803c93f0525D46fbC3ec8Ee4b73da73dC3FD",
5-
"iToken": "0x9034738ccB559FD5c28B0d269E39049a57940611",
6-
"oracle": "0xf36b4688Fa2fEFFB6b7249EFfC3d994821Ffe0ed",
7-
"protocol": "0x6C0e34E84a63E2c98cBb31f24749912D7650375c",
8-
"fEUR": "0xe8914FcE7686dE9807779BB96d3C28778e6DbB54",
9-
"fJPY": "0xc12B3d1a2721b42835be3Fe17032dCa31a431e42",
10-
"fXAU": "0xaF7C5095B8dfB9E9386D58d6D33fbFFdE93c79af",
11-
"fAAPL": "0x2dA1AC5c261f541D04A0a9EE53c3d7c80ac65E73",
12-
"marginProtocol": "0x82680d3421C647195C80862CE9C6B9BC8624eD94",
13-
"l10USDEUR": "0xB91dC76e45c7BA80c8e0d73cFD97A219997cc5d8",
14-
"s10USDEUR": "0x5824f97dB41E399EA6Bf12a12bBE18b3Af2837c4",
15-
"l20USDJPY": "0xC6ab77baf7636a3C483ef6Ef9ef059Ee63789C85",
16-
"s20USDJPY": "0x48C397E5D821828356B14a487cc271E666885B60",
17-
"l20USDXAU": "0x11E66B4D200cE5Dc31773B43b04C4640BaA640b7",
18-
"s20USDXAU": "0xb9Ad7b67Cc1FfA42B989835aB56512043Fc3Eae4",
19-
"l5USDAAPL": "0xa476b2f5592139E9088f4d963BE440410C55A1D7",
20-
"s5USDAAPL": "0xF3ec0C42E7daf2389D7c8c9fEC51505987179740",
21-
"pool": "0xA36bA98A73A446BCD0521FD5a0255Ec81b1fCe59",
22-
"pool2": "0xabde99E93bc45b9cded88D0b9e79bE4221668608"
4+
"moneyMarket": "0x4BAB551e94185fFB0A2C2539A1B3829e5A63E9ed",
5+
"iToken": "0xf7D9c2F13db627cF292Dc01CFa4bD6A2D850cc62",
6+
"oracle": "0x89F2e7a3726e1dBe7d12f386b13435A596A5Bec3",
7+
"syntheticProtocol": "0x87078D357C8EedA62a8C142c81129010CA99FFbD",
8+
"fEUR": "0x462201831F3E843608C3cB2cC7CF2cCdA01D7271",
9+
"fJPY": "0xdE6C9Ee4F1592EE5164B9eeA3543754c4B51a91A",
10+
"fXAU": "0x1a5d99cd0643D83a403913c8471Ca2757bcfcb40",
11+
"fAAPL": "0xD827a54aCd970867Cab145ACF163Dce1c0Af5003",
12+
"marginProtocol": "0xB3b9702C4844EaF2A7934970Ec90f1e97f325C7e",
13+
"marginProtocolSafety": "0x557ab86BA06a67146E4C925DAaB52bD4A72550b2",
14+
"marginPoolRegistry": "0x55cc881358AeA2Bd6a1Fa9B511b36951262eBfad",
15+
"marginPool": "0xAAe87632fAE233Cba4e2175c15717924b88BEE8D",
16+
"marginPool2": "0x08Bf04b6c0BaefEEeD1569Fdb7719b1fc5e9E0B1",
17+
"syntheticPool": "0xb587B74502104cf1002d1F9cF4f7D7662E45A63D",
18+
"syntheticPool2": "0x31e2d63BDbB1822422821b90C29c8716b1707246"
2319
}
Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pragma solidity ^0.6.4;
2+
23
import "@openzeppelin/upgrades/contracts/Initializable.sol";
34
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
45
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
@@ -11,21 +12,18 @@ import "../libs/upgrades/UpgradeReentrancyGuard.sol";
1112

1213
import "../interfaces/PriceOracleInterface.sol";
1314
import "../interfaces/MoneyMarketInterface.sol";
14-
import "../interfaces/LiquidityPoolInterface.sol";
15-
import "./FlowToken.sol";
1615

1716
contract FlowProtocolBase is Initializable, UpgradeOwnable, UpgradeReentrancyGuard {
1817
using SafeMath for uint256;
1918
using SafeERC20 for IERC20;
2019

21-
// DO NOT CHANGE ORDER WHEN UPDATING, ONLY ADDING NEW VARIABLES IS ALLOWED
2220
PriceOracleInterface public oracle;
2321
MoneyMarketInterface public moneyMarket;
2422

25-
uint public maxSpread;
23+
int256 constant MAX_INT = 2**256 / 2 - 1;
24+
uint256 constant MAX_UINT = 2**256 - 1;
2625

27-
int constant MAX_INT = 2**256 / 2 - 1;
28-
uint constant MAX_UINT = 2**256 - 1;
26+
uint256 public maxSpread;
2927

3028
function initialize(PriceOracleInterface _oracle, MoneyMarketInterface _moneyMarket) public initializer {
3129
UpgradeOwnable.initialize(msg.sender);
@@ -39,35 +37,19 @@ contract FlowProtocolBase is Initializable, UpgradeOwnable, UpgradeReentrancyGua
3937
maxSpread = 1 ether / 10; // 10% TODO: pick a justified value
4038
}
4139

42-
function setMaxSpread(uint value) external onlyOwner {
43-
maxSpread = value;
40+
function setMaxSpread(uint256 _maxSpread) external onlyOwner {
41+
maxSpread = _maxSpread;
4442
}
4543

46-
function getPrice(address token) internal returns (uint) {
47-
uint price = oracle.getPrice(token);
44+
function getPrice(address _token) internal returns (uint) {
45+
uint256 price = oracle.getPrice(_token);
4846
require(price > 0, "no oracle price");
49-
return price;
50-
}
51-
52-
function getAskSpread(LiquidityPoolInterface pool, address token) public view returns (uint) {
53-
uint spread = pool.getAskSpread(token);
54-
require(spread > 0, "Token disabled for this pool");
55-
return Math.min(spread, maxSpread);
56-
}
57-
58-
function getBidSpread(LiquidityPoolInterface pool, address token) public view returns (uint) {
59-
uint spread = pool.getBidSpread(token);
60-
require(spread > 0, "Token disabled for this pool");
61-
return Math.min(spread, maxSpread);
62-
}
6347

64-
function getAskPrice(LiquidityPoolInterface pool, address token, uint price) internal view returns (uint) {
65-
uint spread = getAskSpread(pool, token);
66-
return price.add(price.mul(spread).div(1 ether));
48+
return price;
6749
}
6850

69-
function getBidPrice(LiquidityPoolInterface pool, address token, uint price) internal view returns (uint) {
70-
uint spread = getBidSpread(pool, token);
71-
return price.sub(price.mul(spread).div(1 ether));
51+
function _getSpread(uint256 _spread) internal view returns (uint256) {
52+
require(_spread > 0, "Token disabled for this pool");
53+
return Math.min(_spread, maxSpread);
7254
}
7355
}

contracts/impls/LiquidityPool.sol

Lines changed: 8 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,27 @@
11
pragma solidity ^0.6.4;
2+
23
import "@openzeppelin/upgrades/contracts/Initializable.sol";
34
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
45
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
56

67
import "../libs/upgrades/UpgradeOwnable.sol";
78
import "../interfaces/LiquidityPoolInterface.sol";
89
import "../interfaces/MoneyMarketInterface.sol";
9-
import "./FlowProtocol.sol";
10-
import "./FlowToken.sol";
11-
import "./FlowMarginProtocol.sol";
12-
import "./FlowMarginProtocolSafety.sol";
13-
import "./MarginTradingPair.sol";
1410

15-
contract LiquidityPool is Initializable, UpgradeOwnable, LiquidityPoolInterface {
11+
abstract contract LiquidityPool is Initializable, UpgradeOwnable, LiquidityPoolInterface {
1612
using SafeERC20 for IERC20;
1713

18-
// DO NOT CHANGE ORDER WHEN UPDATING, ONLY ADDING NEW VARIABLES IS ALLOWED
19-
uint constant MAX_UINT = 2**256 - 1;
20-
21-
MoneyMarketInterface internal moneyMarket;
22-
uint private spread;
23-
uint private collateralRatio;
24-
25-
address public protocol;
26-
mapping (address => bool) public allowedTokens;
27-
28-
modifier onlyProtocol() {
29-
require(msg.sender == protocol, "Ownable: caller is not the protocol");
30-
_;
31-
}
14+
MoneyMarketInterface public override moneyMarket;
15+
address public override protocol;
3216

33-
function initialize(MoneyMarketInterface _moneyMarket, address _protocol, uint _spread) public initializer {
17+
function initialize(MoneyMarketInterface _moneyMarket, address _protocol) public virtual initializer {
3418
UpgradeOwnable.initialize(msg.sender);
3519

3620
moneyMarket = _moneyMarket;
3721
protocol = _protocol;
38-
spread = _spread;
39-
collateralRatio = 0; // use fToken default
40-
}
41-
42-
function getBidSpread(address fToken) external view override returns (uint) {
43-
if (allowedTokens[fToken]) {
44-
return spread;
45-
}
46-
return 0;
47-
}
48-
49-
function getAskSpread(address fToken) external view override returns (uint) {
50-
if (allowedTokens[fToken]) {
51-
return spread;
52-
}
53-
return 0;
54-
}
55-
56-
function getAdditionalCollateralRatio(address fToken) external view override returns (uint) {
57-
if (allowedTokens[fToken]) {
58-
return collateralRatio;
59-
}
60-
return 0;
61-
}
62-
63-
function approve(address _protocol, uint amount) external onlyOwner {
64-
moneyMarket.iToken().safeApprove(_protocol, amount);
65-
}
66-
67-
function setSpread(uint value) external onlyOwner {
68-
spread = value;
69-
70-
emit SpreadUpdated();
71-
}
72-
73-
function setCollateralRatio(uint value) external onlyOwner {
74-
collateralRatio = value;
75-
76-
emit AdditionalCollateralRatioUpdated();
77-
}
78-
79-
function enableToken(address token) external onlyOwner {
80-
allowedTokens[token] = true;
81-
}
82-
83-
function disableToken(address token) external onlyOwner {
84-
allowedTokens[token] = false;
85-
}
86-
87-
function depositLiquidity(uint _baseTokenAmount) external override returns (uint256) {
88-
moneyMarket.baseToken().safeTransferFrom(msg.sender, address(this), _baseTokenAmount);
89-
moneyMarket.baseToken().approve(address(moneyMarket), _baseTokenAmount);
90-
91-
return moneyMarket.mint(_baseTokenAmount);
92-
}
93-
94-
function withdrawLiquidity(uint _iTokenAmount) external override onlyProtocol returns (uint256) {
95-
return moneyMarket.redeemTo(msg.sender, _iTokenAmount);
96-
}
97-
98-
function withdrawLiquidityOwner(uint _iTokenAmount) external onlyOwner returns (uint256) {
99-
uint256 baseTokenAmount = moneyMarket.redeemTo(msg.sender, _iTokenAmount);
100-
require(
101-
FlowMarginProtocol(protocol).safetyProtocol().isPoolSafe(LiquidityPoolInterface(this)),
102-
"Pool not safe after withdrawal"
103-
);
104-
105-
return baseTokenAmount;
106-
}
107-
108-
function addCollateral(FlowProtocol _protocol, FlowToken token, uint baseTokenAmount) external onlyOwner {
109-
_protocol.addCollateral(token, address(this), baseTokenAmount);
110-
}
111-
112-
function withdrawCollateral(FlowProtocol _protocol, FlowToken token) external onlyOwner {
113-
_protocol.withdrawCollateral(token);
11422
}
11523

116-
function getLiquidity() external override returns (uint256) {
117-
return moneyMarket.iToken().balanceOf(address(this));
24+
function approveToProtocol(uint256 _amount) external override onlyOwner {
25+
moneyMarket.iToken().safeApprove(protocol, _amount);
11826
}
119-
}
27+
}

0 commit comments

Comments
 (0)