Skip to content

Commit 90584da

Browse files
0xclemliamzebedeezyzek
authored
Kovan ovm futures (#1495)
* test that npmignore will include deployment.json NPM ignores files listed in gitignore which is a problem. https://stackoverflow.com/questions/24942161/does-npm-ignore-files-listed-in-gitignore * Deploy kovan-ovm-futures v0.4.0 (Alpha) (#1487) * remove price update constraint from order flow * prepare-deploy * add FuturesMarketSettings to releases * deploy kovan-ovm-futures v0.2.0 * fixes * unignore deployment.json * add FuturesMarketSettings to releases * prepare-deploy * deploy kovan-ovm-futures v0.3.0 * Futures position details (#1479) * Futures accessible margin (#1484) * emit sizeDelta with PositionModified event * emit sizeDelta with PositionModified event (#1485) * emit sizeDelta with PositionModified event * fix * sizeDelta -> tradeSize This is clearer for liquidation flows * deploy kovan-ovm-futures v0.4.0 * test that npmignore will include deployment.json NPM ignores files listed in gitignore which is a problem. https://stackoverflow.com/questions/24942161/does-npm-ignore-files-listed-in-gitignore Co-authored-by: Anton Jurisevic <zyzek@users.noreply.github.com> * Fix futures position id management + tests. (#1492) * prepare-deploy * deploy kovan-ovm-futures v0.4.1 Co-authored-by: liamzebedee <liamzebedee@yahoo.com.au> Co-authored-by: Anton Jurisevic <zyzek@users.noreply.github.com>
1 parent b85ae51 commit 90584da

File tree

5 files changed

+213
-73
lines changed

5 files changed

+213
-73
lines changed

contracts/FuturesMarket.sol

+11-13
Original file line numberDiff line numberDiff line change
@@ -1075,29 +1075,27 @@ contract FuturesMarket is Owned, Proxyable, MixinFuturesMarketSettings, IFutures
10751075
// Record the trade
10761076
if (newPosition.size == 0) {
10771077
// If the position is being closed, we no longer need to track these details.
1078+
delete position.id;
10781079
delete position.size;
10791080
delete position.lastPrice;
10801081
delete position.fundingIndex;
1081-
emitPositionModified(newPosition.id, sender, newPosition.margin, 0, sizeDelta, 0, 0, fee);
1082+
// Note we still emit the old position id in the event to indicate that it's closing.
1083+
emitPositionModified(oldPosition.id, sender, newPosition.margin, 0, sizeDelta, 0, 0, fee);
10821084
} else {
1083-
// New positions get new id's
1085+
uint id;
10841086
if (oldPosition.size == 0) {
1085-
position.id = _nextPositionId;
1087+
// New positions get new ids.
1088+
id = _nextPositionId;
10861089
_nextPositionId += 1;
1090+
position.id = id;
1091+
} else {
1092+
// If an existing position is just being modified, reuse the existing id.
1093+
id = newPosition.id;
10871094
}
10881095
position.size = newPosition.size;
10891096
position.lastPrice = price;
10901097
position.fundingIndex = fundingIndex;
1091-
emitPositionModified(
1092-
newPosition.id,
1093-
sender,
1094-
newPosition.margin,
1095-
newPosition.size,
1096-
sizeDelta,
1097-
price,
1098-
fundingIndex,
1099-
fee
1100-
);
1098+
emitPositionModified(id, sender, newPosition.margin, newPosition.size, sizeDelta, price, fundingIndex, fee);
11011099
}
11021100
}
11031101

publish/deployed/kovan-ovm-futures/deployment.json

+52-52
Large diffs are not rendered by default.

publish/deployed/local-ovm/.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# these files are irrelevant outside of a single developer's machine,
22
# so no need to persist them in source control
3-
owner-actions.json
3+
deployment.json
4+
owner-actions.json

publish/deployed/local-ovm/.npmignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
!deployment.json

test/contracts/FuturesMarket.js

+147-7
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,133 @@ contract('FuturesMarket', accounts => {
15171517
});
15181518
});
15191519

1520+
it('opening a new position gets a new id', async () => {
1521+
await setPrice(baseAsset, toUnit('100'));
1522+
1523+
await futuresMarket.transferMargin(toUnit('1000'), { from: trader });
1524+
await futuresMarket.transferMargin(toUnit('1000'), { from: trader2 });
1525+
1526+
// No position ids at first.
1527+
let { id: positionId } = await futuresMarket.positions(trader);
1528+
assert.bnEqual(positionId, toBN('0'));
1529+
positionId = (await futuresMarket.positions(trader2)).id;
1530+
assert.bnEqual(positionId, toBN('0'));
1531+
1532+
// Trader 1 gets position id 1.
1533+
let tx = await futuresMarket.modifyPosition(toUnit('10'), { from: trader });
1534+
let decodedLogs = await getDecodedLogs({
1535+
hash: tx.tx,
1536+
contracts: [futuresMarket],
1537+
});
1538+
assert.equal(decodedLogs[2].name, 'PositionModified');
1539+
assert.equal(decodedLogs[2].events[0].name, 'id');
1540+
assert.bnEqual(decodedLogs[2].events[0].value, toBN('1'));
1541+
1542+
// trader2 gets the subsequent id
1543+
tx = await futuresMarket.modifyPosition(toUnit('10'), { from: trader2 });
1544+
decodedLogs = await getDecodedLogs({
1545+
hash: tx.tx,
1546+
contracts: [futuresMarket],
1547+
});
1548+
assert.equal(decodedLogs[2].name, 'PositionModified');
1549+
assert.equal(decodedLogs[2].events[0].name, 'id');
1550+
assert.bnEqual(decodedLogs[2].events[0].value, toBN('2'));
1551+
1552+
// And the ids have been modified
1553+
positionId = (await futuresMarket.positions(trader)).id;
1554+
assert.bnEqual(positionId, toBN('1'));
1555+
positionId = (await futuresMarket.positions(trader2)).id;
1556+
assert.bnEqual(positionId, toBN('2'));
1557+
});
1558+
1559+
it('modifying a position retains the same id', async () => {
1560+
await setPrice(baseAsset, toUnit('100'));
1561+
await futuresMarket.transferMargin(toUnit('1000'), { from: trader });
1562+
1563+
// Trader gets position id 1.
1564+
let tx = await futuresMarket.modifyPosition(toUnit('10'), { from: trader });
1565+
let decodedLogs = await getDecodedLogs({
1566+
hash: tx.tx,
1567+
contracts: [futuresMarket],
1568+
});
1569+
assert.equal(decodedLogs[2].name, 'PositionModified');
1570+
assert.equal(decodedLogs[2].events[0].name, 'id');
1571+
assert.bnEqual(decodedLogs[2].events[0].value, toBN('1'));
1572+
1573+
let positionId = (await futuresMarket.positions(trader)).id;
1574+
assert.bnEqual(positionId, toBN('1'));
1575+
1576+
// Modification (but not closure) does not alter the id
1577+
tx = await futuresMarket.modifyPosition(toUnit('-5'), { from: trader });
1578+
decodedLogs = await getDecodedLogs({
1579+
hash: tx.tx,
1580+
contracts: [futuresMarket],
1581+
});
1582+
assert.equal(decodedLogs[1].name, 'PositionModified');
1583+
assert.equal(decodedLogs[1].events[0].name, 'id');
1584+
assert.bnEqual(decodedLogs[1].events[0].value, toBN('1'));
1585+
1586+
// And the ids have been modified
1587+
positionId = (await futuresMarket.positions(trader)).id;
1588+
assert.bnEqual(positionId, toBN('1'));
1589+
});
1590+
1591+
it('closing a position deletes the id but emits in in the event', async () => {
1592+
await setPrice(baseAsset, toUnit('100'));
1593+
await futuresMarket.transferMargin(toUnit('1000'), { from: trader });
1594+
await futuresMarket.transferMargin(toUnit('1000'), { from: trader2 });
1595+
1596+
// Close by closePosition
1597+
let tx = await futuresMarket.modifyPosition(toUnit('10'), { from: trader });
1598+
let decodedLogs = await getDecodedLogs({
1599+
hash: tx.tx,
1600+
contracts: [futuresMarket],
1601+
});
1602+
assert.equal(decodedLogs[2].name, 'PositionModified');
1603+
assert.equal(decodedLogs[2].events[0].name, 'id');
1604+
assert.bnEqual(decodedLogs[2].events[0].value, toBN('1'));
1605+
1606+
let positionId = (await futuresMarket.positions(trader)).id;
1607+
assert.bnEqual(positionId, toBN('1'));
1608+
1609+
tx = await futuresMarket.closePosition({ from: trader });
1610+
decodedLogs = await getDecodedLogs({
1611+
hash: tx.tx,
1612+
contracts: [futuresMarket],
1613+
});
1614+
assert.equal(decodedLogs[1].name, 'PositionModified');
1615+
assert.equal(decodedLogs[1].events[0].name, 'id');
1616+
assert.bnEqual(decodedLogs[1].events[0].value, toBN('1'));
1617+
1618+
positionId = (await futuresMarket.positions(trader)).id;
1619+
assert.bnEqual(positionId, toBN('0'));
1620+
1621+
// Close by modifyPosition
1622+
tx = await futuresMarket.modifyPosition(toUnit('10'), { from: trader2 });
1623+
decodedLogs = await getDecodedLogs({
1624+
hash: tx.tx,
1625+
contracts: [futuresMarket],
1626+
});
1627+
assert.equal(decodedLogs[2].name, 'PositionModified');
1628+
assert.equal(decodedLogs[2].events[0].name, 'id');
1629+
assert.bnEqual(decodedLogs[2].events[0].value, toBN('2'));
1630+
1631+
positionId = (await futuresMarket.positions(trader2)).id;
1632+
assert.bnEqual(positionId, toBN('2'));
1633+
1634+
tx = await futuresMarket.modifyPosition(toUnit('-10'), { from: trader2 });
1635+
decodedLogs = await getDecodedLogs({
1636+
hash: tx.tx,
1637+
contracts: [futuresMarket],
1638+
});
1639+
assert.equal(decodedLogs[1].name, 'PositionModified');
1640+
assert.equal(decodedLogs[1].events[0].name, 'id');
1641+
assert.bnEqual(decodedLogs[1].events[0].value, toBN('2'));
1642+
1643+
positionId = (await futuresMarket.positions(trader)).id;
1644+
assert.bnEqual(positionId, toBN('0'));
1645+
});
1646+
15201647
it('closing a position and opening one after should increment the position id', async () => {
15211648
await transferMarginAndModifyPosition({
15221649
market: futuresMarket,
@@ -1530,16 +1657,29 @@ contract('FuturesMarket', accounts => {
15301657
assert.bnEqual(oldPositionId, toBN('1'));
15311658

15321659
await setPrice(baseAsset, toUnit('200'));
1533-
await futuresMarket.closePosition({ from: trader });
1660+
let tx = await futuresMarket.closePosition({ from: trader });
15341661

1535-
await transferMarginAndModifyPosition({
1536-
market: futuresMarket,
1537-
account: trader,
1538-
fillPrice: toUnit('100'),
1539-
marginDelta: toUnit('1000'),
1540-
sizeDelta: toUnit('10'),
1662+
let decodedLogs = await getDecodedLogs({
1663+
hash: tx.tx,
1664+
contracts: [futuresMarket],
1665+
});
1666+
1667+
// No fee => no fee minting log, so decodedLogs index == 1
1668+
assert.equal(decodedLogs[1].name, 'PositionModified');
1669+
assert.equal(decodedLogs[1].events[0].name, 'id');
1670+
assert.bnEqual(decodedLogs[1].events[0].value, toBN('1'));
1671+
1672+
tx = await futuresMarket.modifyPosition(toUnit('10'), { from: trader });
1673+
1674+
decodedLogs = await getDecodedLogs({
1675+
hash: tx.tx,
1676+
contracts: [futuresMarket],
15411677
});
15421678

1679+
assert.equal(decodedLogs[2].name, 'PositionModified');
1680+
assert.equal(decodedLogs[2].events[0].name, 'id');
1681+
assert.bnEqual(decodedLogs[2].events[0].value, toBN('2'));
1682+
15431683
const { id: newPositionId } = await futuresMarket.positions(trader);
15441684
assert.bnEqual(newPositionId, toBN('2'));
15451685
});

0 commit comments

Comments
 (0)