Skip to content

Commit

Permalink
Update to overlay-market/[email protected] (#30)
Browse files Browse the repository at this point in the history
* Update to overlay-market/[email protected]

* Update pm("overlay-market/[email protected]") and gh actions

* Fix compile issues

* Fix tests/state/conftest.py

* Fix test estimates for state

* Fix test position for state

* Fix tol in position tests for state

* Fix fee disperser conftest for v1-core upgrade
  • Loading branch information
mikeyrf authored Jun 8, 2022
1 parent f1ee10e commit 3eac8c1
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 128 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/test-python.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ jobs:

- name: Create env file for Brownie pm
run: |
touch ~/.brownie/packages/overlay-market/[email protected].2/.env
echo WEB3_INFURA_PROJECT_ID=${{ secrets.WEB3_INFURA_PROJECT_ID }} >> ~/.brownie/packages/overlay-market/[email protected].2/.env
echo ETHERSCAN_TOKEN=${{ secrets.ETHERSCAN_TOKEN }} >> ~/.brownie/packages/overlay-market/[email protected].2/.env
cat ~/.brownie/packages/overlay-market/[email protected].2/.env
touch ~/.brownie/packages/overlay-market/[email protected].4/.env
echo WEB3_INFURA_PROJECT_ID=${{ secrets.WEB3_INFURA_PROJECT_ID }} >> ~/.brownie/packages/overlay-market/[email protected].4/.env
echo ETHERSCAN_TOKEN=${{ secrets.ETHERSCAN_TOKEN }} >> ~/.brownie/packages/overlay-market/[email protected].4/.env
cat ~/.brownie/packages/overlay-market/[email protected].4/.env
- name: Run Tests
run: brownie test -vv -s --gas
4 changes: 2 additions & 2 deletions brownie-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dotenv: .env
# require OpenZepplin, Uniswap Contracts
dependencies:
- OpenZeppelin/[email protected]
- overlay-market/[email protected].2
- overlay-market/[email protected].4
- Uniswap/[email protected]
- Uniswap/[email protected]

Expand All @@ -23,6 +23,6 @@ compiler:
runs: 800
remappings:
- "@openzeppelin=OpenZeppelin/[email protected]"
- "@overlay/v1-core=overlay-market/[email protected].2"
- "@overlay/v1-core=overlay-market/[email protected].4"
- "@uniswap/v3-core=Uniswap/[email protected]"
- "@uniswap/v3-periphery=Uniswap/[email protected]"
27 changes: 21 additions & 6 deletions contracts/state/OverlayV1EstimateState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "@overlay/v1-core/contracts/libraries/FixedPoint.sol";
import "@overlay/v1-core/contracts/libraries/Oracle.sol";
import "@overlay/v1-core/contracts/libraries/Position.sol";
import "@overlay/v1-core/contracts/libraries/Risk.sol";
import "@overlay/v1-core/contracts/libraries/Tick.sol";

import "../interfaces/state/IOverlayV1EstimateState.sol";

Expand All @@ -19,6 +20,7 @@ abstract contract OverlayV1EstimateState is
OverlayV1PriceState,
OverlayV1OIState
{
using FixedCast for uint256;
using FixedPoint for uint256;
using Position for Position.Info;

Expand All @@ -37,18 +39,31 @@ abstract contract OverlayV1EstimateState is
uint256 oi = _oiFromNotional(data, notional);
uint256 fractionOfCapOi = _fractionOfCapOi(market, data, oi);

// get the attributes needed to calculate position oiShares:
// oiLong/Short, oiLongShares/oiShortShares
(uint256 oiLong, uint256 oiShort) = _ois(market);
uint256 oiShares = Position.calcOiShares(
oi,
isLong ? oiLong : oiShort,
isLong ? market.oiLongShares() : market.oiShortShares()
);

// prices
uint256 midPrice = _mid(data);
uint256 price = isLong
? _ask(market, data, fractionOfCapOi)
: _bid(market, data, fractionOfCapOi);

// TODO: test
position_ = Position.Info({
notional: uint96(notional),
debt: uint96(debt),
entryToMidRatio: Position.calcEntryToMidRatio(price, midPrice),
notionalInitial: uint96(notional),
debtInitial: uint96(debt),
midTick: Tick.priceToTick(midPrice),
entryTick: Tick.priceToTick(price),
isLong: isLong,
liquidated: false,
oiShares: oi
oiShares: uint240(oiShares),
fractionRemaining: FixedPoint.ONE.toUint16Fixed()
});
}

Expand All @@ -57,7 +72,7 @@ abstract contract OverlayV1EstimateState is
uint256 fraction = FixedPoint.ONE;

// debt estimate is simply initial debt of position
debt_ = position.debtCurrent(fraction);
debt_ = Position.debtInitial(position, fraction);
}

function _costEstimate(Position.Info memory position) internal view returns (uint256 cost_) {
Expand All @@ -84,7 +99,7 @@ abstract contract OverlayV1EstimateState is
uint256 maintenanceMarginFraction = market.params(
uint256(Risk.Parameters.MaintenanceMarginFraction)
);
uint256 q = position.notionalInitial(FixedPoint.ONE);
uint256 q = Position.notionalInitial(position, FixedPoint.ONE);
maintenanceMargin_ = q.mulUp(maintenanceMarginFraction);
}

Expand Down
30 changes: 17 additions & 13 deletions contracts/state/OverlayV1PositionState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,26 @@ abstract contract OverlayV1PositionState is
) internal view returns (Position.Info memory position_) {
bytes32 key = keccak256(abi.encodePacked(owner, id));
(
uint96 notional,
uint96 debt,
uint48 entryToMidRatio,
uint96 notionalInitial,
uint96 debtInitial,
int24 midTick,
int24 entryTick,
bool isLong,
bool liquidated,
uint256 oiShares
uint240 oiShares,
uint16 fractionRemaining
) = market.positions(key);

// assemble the position info struct
position_ = Position.Info({
notional: notional,
debt: debt,
entryToMidRatio: entryToMidRatio,
notionalInitial: notionalInitial,
debtInitial: debtInitial,
midTick: midTick,
entryTick: entryTick,
isLong: isLong,
liquidated: liquidated,
oiShares: oiShares
oiShares: oiShares,
fractionRemaining: fractionRemaining
});
}

Expand All @@ -56,7 +60,7 @@ abstract contract OverlayV1PositionState is
uint256 fraction = FixedPoint.ONE;

// return the debt
debt_ = position.debtCurrent(fraction);
debt_ = Position.debtInitial(position, fraction);
}

/// @dev current cost basis of individual position
Expand Down Expand Up @@ -101,9 +105,9 @@ abstract contract OverlayV1PositionState is
uint256 fraction = FixedPoint.ONE;

// get attributes needed to calculate current collateral amount:
// notionalInitial, debtCurrent, oiInitial, oiCurrent
uint256 q = position.notionalInitial(fraction);
uint256 d = position.debtCurrent(fraction);
// notionalInitial, debtInitial, oiInitial, oiCurrent
uint256 q = Position.notionalInitial(position, fraction);
uint256 d = Position.debtInitial(position, fraction);
uint256 oiInitial = position.oiInitial(fraction);

// calculate oiCurrent from aggregate oi values
Expand Down Expand Up @@ -305,7 +309,7 @@ abstract contract OverlayV1PositionState is
uint256 maintenanceMarginFraction = market.params(
uint256(Risk.Parameters.MaintenanceMarginFraction)
);
uint256 q = position.notionalInitial(FixedPoint.ONE);
uint256 q = Position.notionalInitial(position, FixedPoint.ONE);
maintenanceMargin_ = q.mulUp(maintenanceMarginFraction);
}

Expand Down
12 changes: 10 additions & 2 deletions tests/feedisperser/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

@pytest.fixture(scope="module")
def ovl_v1_core(pm):
return pm("overlay-market/[email protected].2")
return pm("overlay-market/[email protected].4")


@pytest.fixture(scope="module")
Expand Down Expand Up @@ -43,14 +43,22 @@ def governor_role():


@pytest.fixture(scope="module", params=[8000000])
def create_token(ovl_v1_core, gov, alice, bob, governor_role, request):
def create_token(ovl_v1_core, gov, alice, bob, minter_role, governor_role,
request):
sup = request.param

def create_token(supply=sup):
ovl = ovl_v1_core.OverlayV1Token
tok = gov.deploy(ovl)

# grant governor role
tok.grantRole(governor_role, gov, {"from": gov})

# mint the token then renounce minter role
tok.grantRole(minter_role, gov, {"from": gov})
tok.mint(gov, supply * 10 ** tok.decimals(), {"from": gov})
tok.renounceRole(minter_role, gov, {"from": gov})

tok.transfer(alice, (supply/2) * 10 ** tok.decimals(), {"from": gov})
tok.transfer(bob, (supply/2) * 10 ** tok.decimals(), {"from": gov})
return tok
Expand Down
37 changes: 21 additions & 16 deletions tests/state/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

@pytest.fixture(scope="module")
def ovl_v1_core(pm):
return pm("overlay-market/[email protected].2")
return pm("overlay-market/[email protected].4")


@pytest.fixture(scope="module")
Expand Down Expand Up @@ -32,21 +32,6 @@ def fee_recipient(accounts):
yield accounts[4]


@pytest.fixture(scope="module", params=[8000000])
def create_token(ovl_v1_core, gov, alice, bob, request):
sup = request.param

def create_token(supply=sup):
ovl = ovl_v1_core.OverlayV1Token
tok = gov.deploy(ovl)
tok.mint(gov, supply * 10 ** tok.decimals(), {"from": gov})
tok.transfer(alice, (supply/2) * 10 ** tok.decimals(), {"from": gov})
tok.transfer(bob, (supply/2) * 10 ** tok.decimals(), {"from": gov})
return tok

yield create_token


@pytest.fixture(scope="module")
def minter_role():
yield web3.solidityKeccak(['string'], ["MINTER"])
Expand All @@ -62,6 +47,26 @@ def governor_role():
yield web3.solidityKeccak(['string'], ["GOVERNOR"])


@pytest.fixture(scope="module", params=[8000000])
def create_token(ovl_v1_core, gov, alice, bob, minter_role, request):
sup = request.param

def create_token(supply=sup):
ovl = ovl_v1_core.OverlayV1Token
tok = gov.deploy(ovl)

# mint the token then renounce minter role
tok.grantRole(minter_role, gov, {"from": gov})
tok.mint(gov, supply * 10 ** tok.decimals(), {"from": gov})
tok.renounceRole(minter_role, gov, {"from": gov})

tok.transfer(alice, (supply/2) * 10 ** tok.decimals(), {"from": gov})
tok.transfer(bob, (supply/2) * 10 ** tok.decimals(), {"from": gov})
return tok

yield create_token


@pytest.fixture(scope="module")
def ovl(create_token):
yield create_token()
Expand Down
31 changes: 22 additions & 9 deletions tests/state/test_estimate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from brownie.test import given, strategy
from decimal import Decimal

from .utils import calculate_mid_ratio, RiskParameter
from .utils import price_to_tick, RiskParameter


@given(
Expand All @@ -21,9 +21,18 @@ def test_position_estimate(state, market, feed, alice, ovl, leverage, is_long):
# NOTE: state.mid() tested in test_price.py
mid_price = state.mid(market)

# calculate the oi
# oi total and oi total shares on side
# NOTE: state.ois() tested in test_oi.py
oi_long, oi_short = state.ois(market)
oi_total = oi_long if is_long else oi_short
oi_total_shares = market.oiLongShares() \
if is_long else market.oiShortShares()

# calculate the oi and oi shares
# NOTE: state.fractionOfCapOi() tested in test_oi.py
oi = int(Decimal(notional) * Decimal(1e18) / Decimal(mid_price))
oi_shares = int(Decimal(oi) * Decimal(oi_total_shares)
/ Decimal(oi_total)) if oi_total > 0 else oi
fraction_oi = state.fractionOfCapOi(market, oi)

# get the entry price
Expand All @@ -35,13 +44,16 @@ def test_position_estimate(state, market, feed, alice, ovl, leverage, is_long):
expect_notional = notional
expect_debt = expect_notional - collateral
expect_is_long = is_long
expect_mid_ratio = calculate_mid_ratio(entry_price, mid_price)
expect_mid_tick = price_to_tick(mid_price)
expect_entry_tick = price_to_tick(entry_price)
expect_liquidated = False
expect_oi_shares = oi
expect_oi_shares = oi_shares
expect_fraction_remaining = 10000

# check market position is same as position returned from state
expect = (expect_notional, expect_debt, expect_mid_ratio, expect_is_long,
expect_liquidated, expect_oi_shares)
expect = (expect_notional, expect_debt, expect_mid_tick, expect_entry_tick,
expect_is_long, expect_liquidated, expect_oi_shares,
expect_fraction_remaining)
actual = state.positionEstimate(market, collateral, leverage, is_long)
assert expect == actual

Expand Down Expand Up @@ -93,13 +105,13 @@ def test_oi_estimate(state, market, feed, alice, ovl, is_long):
mid_price = state.mid(market)

# calculate the oi
# NOTE: state.fractionOfCapOi() tested in test_oi.py
oi = int(Decimal(notional) * Decimal(1e18) / Decimal(mid_price))

# check position's oi is same as position returned from state
# NOTE: rel 1e-4 given tick precision to 1bps
expect = oi
actual = state.oiEstimate(market, collateral, leverage, is_long)
assert expect == actual
assert expect == approx(actual, rel=1e-4)


@given(is_long=strategy('bool'))
Expand Down Expand Up @@ -166,7 +178,8 @@ def test_liquidation_price_estimate(state, market, feed, alice, ovl, is_long):
if is_long else entry_price + dp

# check position's maintenance is same as position returned from state
# NOTE: rel 1e-4 given tick precision to 1bps
expect = int(expect_liquidation_price)
actual = int(state.liquidationPriceEstimate(
market, collateral, leverage, is_long))
assert expect == approx(actual)
assert expect == approx(actual, rel=1e-4)
Loading

0 comments on commit 3eac8c1

Please sign in to comment.