You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## [C-1] Stale price of closed markets results in breaking core protocol functionality
9
+
10
+
This update is intended to allow for markets that use assets outside of crypto, that are not traded and thus priced 24/7, and instead have market operating hours, like US stocks. This results in the oracle no longer updating the price once the markets have closed, resulting in stale data errors when querying the prices normally. In order to allow for important functionality like liquidations of accounts that contain positions in these markets while they are closed, the function [getCurrentPricesWithClosedMarkets()](https://github.com/Polynomial-Protocol/fx-contracts/blob/4d7e3512dfcbe3b2d009252f846fd64dc5d3b722/markets/perps-market/contracts/storage/PerpsPrice.sol#L85-L131) is used, where the owner can close markets via [closeMarkets()](https://github.com/Polynomial-Protocol/fx-contracts/blob/4d7e3512dfcbe3b2d009252f846fd64dc5d3b722/markets/perps-market/contracts/modules/MarketCloseModule.sol#L48-L63) which stores the current price as the price at market close and closes the market. This allows for position value to still be calculated when markets close and allows liquidations to occur. However other important functionality like [reportedDebt()](https://github.com/Polynomial-Protocol/fx-contracts/blob/4d7e3512dfcbe3b2d009252f846fd64dc5d3b722/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol#L114-L138), used by the core protocol to determine markets it supports debt, would revert if any market that is closed, locking key functionality for the protocol.
11
+
12
+
**Remediations to Consider**
13
+
14
+
Allow for closed market handling in [getCurrentPrices()](https://github.com/Polynomial-Protocol/fx-contracts/blob/4d7e3512dfcbe3b2d009252f846fd64dc5d3b722/markets/perps-market/contracts/storage/PerpsPrice.sol#L45-L83) rather then use custom handling for liquidations via [getCurrentPricesWithClosedMarkets()](https://github.com/Polynomial-Protocol/fx-contracts/blob/4d7e3512dfcbe3b2d009252f846fd64dc5d3b722/markets/perps-market/contracts/storage/PerpsPrice.sol#L85-L131).
## [H-1] Not closing markets in time can lock key protocol functionality
26
+
27
+
For the reasons described in C-1, once markets are closed the oracle will no longer update the price and would resulting stale pricing which effects core functionality. [closeMarkets()](https://github.com/Polynomial-Protocol/fx-contracts/blob/4d7e3512dfcbe3b2d009252f846fd64dc5d3b722/markets/perps-market/contracts/modules/MarketCloseModule.sol#L48-L63) is intended to be called at market close to store the last price and mark as close to allow for custom handling via [getCurrentPricesWithClosedMarkets()](https://github.com/Polynomial-Protocol/fx-contracts/blob/4d7e3512dfcbe3b2d009252f846fd64dc5d3b722/markets/perps-market/contracts/storage/PerpsPrice.sol#L85-L131). However, if for whatever reason the owner does not manage to call to close a market within 60 seconds of the market close price being updated, then they will be prevent from doing so, as it will revert due to the stale closing price. This would then result in the same issues described in C-1, even if resolved as suggested, until the market is able to be opened.
28
+
29
+
**Remediations to Consider**
30
+
31
+
Allow for a market to be closed even if the data is stale to prevent locking the protocol if a market is missed.
[getCurrentPricesWithClosedMarkets()](https://github.com/Polynomial-Protocol/fx-contracts/blob/4d7e3512dfcbe3b2d009252f846fd64dc5d3b722/markets/perps-market/contracts/storage/PerpsPrice.sol#L85-L131) is intended to be the same as [getCurrentPrices()](https://github.com/Polynomial-Protocol/fx-contracts/blob/4d7e3512dfcbe3b2d009252f846fd64dc5d3b722/markets/perps-market/contracts/storage/PerpsPrice.sol#L45-L83), with the exception of handling closed markets and use of strict tolerance as it is supposed to be used for liquidations which only use strict price tolerance:
45
+
46
+
```solidity
47
+
bytes32[] memory runtimeKeys = new bytes32[](0);
48
+
// tolerance is STRICT (no runtime keys supplied here; mirrors previous behavior)
This can result in inaccurate pricing for liquidations, and wrong determinations if an account should be liquidated or not.
86
+
87
+
**Remediations to Consider**
88
+
89
+
Use the strict tolerance logic of `getCurrentPrice()`, or alternatively adjust getCurrentPrice() to handle closed markets and remove `getCurrentPricesWithClosedMarkets()`.
90
+
</field>
91
+
</item>
92
+
93
+
<item>
94
+
<fieldname="topic">Inconsistency</field>
95
+
<fieldname="impact">medium</field>
96
+
<fieldname="chance">low</field>
97
+
<fieldname="status">ack</field>
98
+
<fieldname="content">
99
+
## [M-1] Potentially inconsistent rollover fees
100
+
101
+
Currently rollover fees are only applied when an account is updated, using the value of the markets rollover fees at the time of update. This is fine if the rollover fee does not change since the last position update, however if it does change potentially to incentivize LPs during high volatility, then the user would be charged the new fee, be it higher or lower than the last, when they next update their position. This leads to potential over or under charging of fees, and inconsistent rewards for LP providers. It could also result in cases where if the rollover fee is increased temporarily, for high volatility, then a user may delay updating their position until the rollover fee is reduced in order to reduce the fees charged to them.
102
+
103
+
**Remediations to Consider**
104
+
105
+
Consider keeping tabs of a cumulative fee rather than just a last updated timestamp, if the account and market each has a cumulative fee of time * current rolloverFee, then after a fee change the new fee would only be applied for time after the update, and not used for the entire time since an account was last updated, resulting in accurate fees. Additionally, you could consider adding a public method that allows charging fees owed by an account, since fees to the protocol are only applied on update which could never occur. Allowing for inactive accounts with large fees to be collected.
106
+
107
+
</field>
108
+
<fieldname="response">
109
+
rolloverFee is operated as static for now and we do not expect changes soon.
110
+
Interim: We will not modify rolloverFee until the cumulative accounting fix is live. If an urgent change is required, we will announce the effective block in advance.
111
+
Planned fix: Add a cumulative rolloverFeeIndex with per-account lastIndex, and a keeper method to charge inactive accounts. Targeted for the next upgrade window.
112
+
</field>
113
+
</item>
114
+
115
+
<item>
116
+
<fieldname="topic">Informational</field>
117
+
<fieldname="content">
118
+
## [I-1] Positions in closed markets cannot be modified until the market is reopened
119
+
120
+
The intended behaviour of handling closed markets is that positions cannot be modified while they are closed, acting similarly to traditional stock markets the underlying assets are traded on. This is to prevent trading on information that would effect price but is not tracked by the oracle, leading to an unfair edge. Although this behaviour is not explicitly handled, when querying the price of the asset will revert due to stale data, preventing updating the position as intended.
121
+
122
+
Users should be aware that these positions are limited to the hours of the traditional markets they are traded on, unlike other markets on polynomial.
123
+
</field>
124
+
<fieldname="response">
125
+
This is intended. During off-market hours the oracle is stale. The app will display data based on the last official close price and clearly indicate “Market closed.” Users cannot modify positions during this period.
126
+
Planned: Add explicit market-hours checks with clear errors and a read API for next open and close times.
0 commit comments