Skip to content
This repository has been archived by the owner on Jan 16, 2022. It is now read-only.

C4 underwater fixes #120

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
22 changes: 13 additions & 9 deletions contracts/collateral/OverlayV1OVLCollateral.sol
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ contract OverlayV1OVLCollateral is ERC1155Supply {

/**
@notice Build a position on Overlay with OVL collateral
@dev This interacts with an Overlay Market to register oi and hold
@dev This interacts with an Overlay Market to register oi and hold
positions on behalf of users.
@dev Build event emitted
@param _market The address of the desired market to interact with
Expand Down Expand Up @@ -336,14 +336,18 @@ contract OverlayV1OVLCollateral is ERC1155Supply {

emit Unwind(pos.market, _positionId, _userOi, _userDebt);

// TODO: think through edge case of underwater position ... and fee adjustments ...
uint _feeAmount = _userNotional.mulUp(mothership.fee());

uint _userValueAdjusted = _userNotional - _feeAmount;
if (_userValueAdjusted > _userDebt) _userValueAdjusted -= _userDebt;
else _userValueAdjusted = 0;
if (_userValueAdjusted > _userDebt) {
_userValueAdjusted -= _userDebt;
} else {
// underwater position set to zero value with fees lowered appropriately
_userValueAdjusted = 0;
_feeAmount = _userNotional > _userDebt ? _userNotional - _userDebt : 0;
}

fees += _feeAmount; // adds to fee pot, which is transferred on update
fees += _feeAmount; // adds to fee pot, which is transferred on disburse

pos.debt -= _userDebt;
pos.cost -= _userCost;
Expand All @@ -355,16 +359,16 @@ contract OverlayV1OVLCollateral is ERC1155Supply {
if (_userCost < _userValueAdjusted) {

ovl.transferMint(
msg.sender,
_userCost,
msg.sender,
_userCost,
_userValueAdjusted - _userCost
);

} else {

ovl.transferBurn(
msg.sender,
_userValueAdjusted,
msg.sender,
_userValueAdjusted,
_userCost - _userValueAdjusted
);

Expand Down
2 changes: 1 addition & 1 deletion contracts/libraries/Position.sol
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ library Position {
bool _long = _self.isLong;

if (_long) isUnder = __oi.mulDown(priceFrame) < _self.debt;
else isUnder = __oi.mulDown(priceFrame) + _self.debt < ( __oi * 2 );
else isUnder = __oi.mulDown(priceFrame) + _self.debt > ( __oi * 2 );

}

Expand Down
27 changes: 19 additions & 8 deletions tests/markets/collateral/ovl/test_unwind.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ def test_unwind_expected_fee(
notional = val + debt_pos

fee = notional * (mothership.fee() / 1e18)
if notional - debt_pos < fee:
# lower fee is position is underwater (value < 0)
fee = notional - debt_pos

fees_now = ovl_collateral.fees() / 1e18

Expand Down Expand Up @@ -467,10 +470,11 @@ def test_unwind_pnl_mint_burn(

(oi, oi_shares, price_frame) = market.positionInfo(is_long, price_point)

# Unwind position

# State prior to unwind
exit_price_ix = market.pricePointNextIndex()
fees_prior = ovl_collateral.fees()

# Unwind position
tx_unwind = ovl_collateral.unwind(
pid,
bob_balance,
Expand Down Expand Up @@ -498,18 +502,21 @@ def test_unwind_pnl_mint_burn(
val = oi_pos * 2
val = val - min(val, debt_pos + oi_pos * price_frame)

notional = val + debt_pos

fee = notional * (mothership.fee() / 1e18)

# Other metrics
debt = bob_balance * (debt_pos/total_pos_shares)
cost = bob_balance * (cost_pos/total_pos_shares)

value_adjusted = notional - fee
notional = val + debt

value_adjusted = value_adjusted - debt if value_adjusted > debt else 0
# divide by 1e18 since mothership.fee() is a fraction
fee = notional * (mothership.fee() / 1e18)

value_adjusted = notional - debt - fee
if notional - debt < fee:
value_adjusted = 0
fee = notional - debt if notional > debt else 0

# check expected pnl matches actual
exp_pnl = value_adjusted - cost

for _, v in enumerate(tx_unwind.events['Transfer']):
Expand All @@ -519,3 +526,7 @@ def test_unwind_pnl_mint_burn(
act_pnl = v['value']

assert exp_pnl == approx(act_pnl)

# check fees added
fees_now = ovl_collateral.fees()
assert fee + fees_prior == approx(fees_now)
9 changes: 5 additions & 4 deletions tests/markets/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
PRICE_POINTS_START = 50
PRICE_POINTS_END = 100


PRICE_WINDOW_MACRO = 3600
PRICE_WINDOW_MICRO = 600

Expand Down Expand Up @@ -165,12 +166,12 @@ def feed_infos():
depth_path = '../../feeds/univ3_axs_weth'

raw_uni_framed_market_path = os.path.join(base,
market_path +
'_raw_uni_framed.json')
market_path
+ '_raw_uni_framed.json')
reflected_market_path = os.path.join(base, market_path + '_reflected.json')
raw_uni_framed_depth_path = os.path.join(base,
depth_path +
'_raw_uni_framed.json')
depth_path
+ '_raw_uni_framed.json')
reflected_depth_path = os.path.join(base, depth_path + '_reflected.json')

with open(os.path.normpath(raw_uni_framed_market_path)) as f:
Expand Down