Skip to content

Commit

Permalink
Merge pull request #85 from laminar-protocol/margin-swap-rates-per-pair
Browse files Browse the repository at this point in the history
MarginProtocol: Swap rates per token pair
  • Loading branch information
gorgos authored Apr 30, 2020
2 parents 3d7cba1 + a917adb commit 22f9278
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 69 deletions.
43 changes: 28 additions & 15 deletions contracts/impls/margin/MarginFlowProtocol.sol
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,14 @@ contract MarginFlowProtocol is FlowProtocolBase {
mapping (MarginLiquidityPoolInterface => mapping(address => bool)) public traderHasPaidFees;
mapping (MarginLiquidityPoolInterface => mapping(address => bool)) public traderIsMarginCalled;
mapping(address => mapping (address => bool)) public tradingPairWhitelist;
mapping (address => mapping(address => mapping (bool => Percentage.Percent))) public currentSwapRates;

Percentage.Percent public currentSwapRate;
uint256 public minLeverage;
uint256 public maxLeverage;
uint256 public minLeverageAmount;
uint256 public rateUnit;
uint256 public swapRateUnit;
bool constant public LONG = true;
bool constant public SHORT = false;
uint256 constant public TRADER_MARGIN_CALL_FEE = 20 ether; // TODO
uint256 constant public TRADER_LIQUIDATION_FEE = 60 ether; // TODO

Expand All @@ -150,51 +152,62 @@ contract MarginFlowProtocol is FlowProtocolBase {
* @dev Initialize the MarginFlowProtocol.
* @param _oracle The price oracle
* @param _moneyMarket The money market.
* @param _safetyProtocol The _safetyProtocol.
* @param _liquidityPoolRegistry The liquidity pool registry.
* @param _initialSwapRate The initial swap rate as percentage.
* @param _initialMinLeverage The _initialMinLeverage.
* @param _initialMaxLeverage The _initialMaxLeverage.
* @param _initialMinLeverageAmount The _initialMinLeverageAmount.
* @param _swapRateUnit The _swapRateUnit.
*/
function initialize(
PriceOracleInterface _oracle,
MoneyMarketInterface _moneyMarket,
MarginFlowProtocolSafety _safetyProtocol,
MarginLiquidityPoolRegistry _liquidityPoolRegistry,
uint256 _initialSwapRate,
uint256 _initialMinLeverage,
uint256 _initialMaxLeverage,
uint256 _initialMinLeverageAmount,
uint256 _rateUnit
uint256 _swapRateUnit
) external initializer {
FlowProtocolBase.initialize(_oracle, _moneyMarket);
safetyProtocol = _safetyProtocol;
liquidityPoolRegistry = _liquidityPoolRegistry;
currentSwapRate = Percentage.Percent(_initialSwapRate);
minLeverage = _initialMinLeverage;
maxLeverage = _initialMaxLeverage;
minLeverageAmount = _initialMinLeverageAmount;
rateUnit = _rateUnit;
swapRateUnit = _swapRateUnit;
}

/**
* @dev Add new trading pair, only for the owner.
* @param _base The base token.
* @param _quote The quote token.
* @param _swapRateLong The swap rate as percentage for longs.
* @param _swapRateShort The swap rate as percentage for shorts.
*/
function addTradingPair(address _base, address _quote) external onlyOwner {
function addTradingPair(address _base, address _quote, uint256 _swapRateLong, uint256 _swapRateShort) external onlyOwner {
require(_base != address(0) && _quote != address(0), "0");
require(_base != _quote, "TP3");
require(!tradingPairWhitelist[_base][_quote], "TP2");

currentSwapRates[_base][_quote][LONG] = Percentage.Percent(_swapRateLong);
currentSwapRates[_base][_quote][SHORT] = Percentage.Percent(_swapRateShort);
tradingPairWhitelist[_base][_quote] = true;

emit NewTradingPair(_base, _quote);
}

/**
* @dev Set new swap rate, only for the owner.
* @param _newSwapRate The new swap rate as percentage.
* @dev Set new swap rate for token pair, only for the owner.
* @param _base The base token.
* @param _quote The quote token.
* @param _newSwapRateLong The new swap rate as percentage for longs.
* @param _newSwapRateShort The new swap rate as percentage for shorts.
*/
function setCurrentSwapRate(uint256 _newSwapRate) external onlyOwner {
require(_newSwapRate > 0, "0");
currentSwapRate = Percentage.Percent(_newSwapRate);
function setCurrentSwapRateForPair(address _base, address _quote, uint256 _newSwapRateLong, uint256 _newSwapRateShort) external onlyOwner {
require(_newSwapRateLong > 0 && _newSwapRateShort > 0, "0");
currentSwapRates[_base][_quote][LONG] = Percentage.Percent(_newSwapRateLong);
currentSwapRates[_base][_quote][SHORT] = Percentage.Percent(_newSwapRateShort);
}

/**
Expand Down Expand Up @@ -427,7 +440,7 @@ contract MarginFlowProtocol is FlowProtocolBase {
Position memory position = positionsById[_positionId];

uint256 timeDeltaInSeconds = now.sub(position.timeWhenOpened);
uint256 daysSinceOpen = timeDeltaInSeconds.div(rateUnit);
uint256 daysSinceOpen = timeDeltaInSeconds.div(swapRateUnit);
uint256 leveragedDebitsAbs = position.leveragedDebitsInUsd >= 0
? uint256(position.leveragedDebitsInUsd)
: uint256(-position.leveragedDebitsInUsd);
Expand Down Expand Up @@ -578,7 +591,7 @@ contract MarginFlowProtocol is FlowProtocolBase {
int256(leveragedDebits).mul(debitSignum),
int256(leveragedHeldInUsd).mul(debitSignum),
marginHeld,
currentSwapRate,
currentSwapRates[_pair.base][_pair.quote][_leverage > 0 ? LONG : SHORT],
now
);

Expand Down
16 changes: 11 additions & 5 deletions cucumber/step-definitions/margin.steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ const parseAmount = (amount: string): BN => {
};

const parseSwapRate = (amount: string): BN => {
const parsed = amount.replace('%', '');
const parsed = amount.replace(/%|-/g, '');
const onePercentSpread = new BN(web3.utils.toWei('1')).div(new BN(100));

return onePercentSpread.mul(new BN(parsed));
};

Expand Down Expand Up @@ -257,7 +258,7 @@ Given('oracle price', async (table: TableDefinition) => {

Given('margin spread', async (table: TableDefinition) => {
for (const [pair, value] of table.rows()) {
const spreadValue = parseAmount(value); // TODO? .div(new BN(10000));
const spreadValue = parseAmount(value);
const { baseAddress, quoteAddress } = parseTradingPair(pair);

await sendTx({
Expand Down Expand Up @@ -297,13 +298,16 @@ Given(

Given('margin set swap rate', async (table: TableDefinition) => {
for (const [pair, long, short] of table.rows()) {
const { baseAddress, quoteAddress } = parseTradingPair(pair); // TODO
const { baseAddress, quoteAddress } = parseTradingPair(pair);
const longSwapRate = parseSwapRate(long);
const shortSpread = parseSwapRate(short); // TODO
const shortSpread = parseSwapRate(short);

await sendTx({
contractMethod: flowMarginProtocolContract.methods.setCurrentSwapRate(
contractMethod: flowMarginProtocolContract.methods.setCurrentSwapRateForPair(
baseAddress,
quoteAddress,
longSwapRate,
shortSpread,
),
to: flowMarginProtocolAddress,
});
Expand All @@ -322,6 +326,8 @@ Given(/margin enable trading pair (\D*)/, async (tradingPair: string) => {
contractMethod: flowMarginProtocolContract.methods.addTradingPair(
baseAddress,
quoteAddress,
1,
1,
),
to: flowMarginProtocolAddress,
});
Expand Down
57 changes: 48 additions & 9 deletions migrations/deploy_contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@ module.exports = (artifacts: Truffle.Artifacts, web3: Web3) => {
moneyMarket.address,
marginProtocolSafety.address,
marginLiquidityPoolRegistry.address,
initialSwapRate,
1,
50,
2,
Expand Down Expand Up @@ -298,14 +297,54 @@ module.exports = (artifacts: Truffle.Artifacts, web3: Web3) => {

const usd = await moneyMarket.baseToken();

await marginProtocol.addTradingPair(fEUR.address, usd);
await marginProtocol.addTradingPair(usd, fEUR.address);
await marginProtocol.addTradingPair(fJPY.address, usd);
await marginProtocol.addTradingPair(usd, fJPY.address);
await marginProtocol.addTradingPair(fXAU.address, usd);
await marginProtocol.addTradingPair(usd, fXAU.address);
await marginProtocol.addTradingPair(fAAPL.address, usd);
await marginProtocol.addTradingPair(usd, fAAPL.address);
await marginProtocol.addTradingPair(
fEUR.address,
usd,
initialSwapRate,
initialSwapRate,
);
await marginProtocol.addTradingPair(
usd,
fEUR.address,
initialSwapRate,
initialSwapRate,
);
await marginProtocol.addTradingPair(
fJPY.address,
usd,
initialSwapRate,
initialSwapRate,
);
await marginProtocol.addTradingPair(
usd,
fJPY.address,
initialSwapRate,
initialSwapRate,
);
await marginProtocol.addTradingPair(
fXAU.address,
usd,
initialSwapRate,
initialSwapRate,
);
await marginProtocol.addTradingPair(
usd,
fXAU.address,
initialSwapRate,
initialSwapRate,
);
await marginProtocol.addTradingPair(
fAAPL.address,
usd,
initialSwapRate,
initialSwapRate,
);
await marginProtocol.addTradingPair(
usd,
fAAPL.address,
initialSwapRate,
initialSwapRate,
);

// approve default account

Expand Down
Loading

0 comments on commit 22f9278

Please sign in to comment.