-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Fix] Add maximum for intent price deviation #468
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,6 +94,19 @@ library GuaranteeLib { | |
return self.taker().mul(price).sub(self.notional); | ||
} | ||
|
||
/// @notice Returns the price deviation of the guarantee from the oracle price | ||
/// @dev The price deviation is (intent price - oracle price) / min(intent price, oracle price) | ||
/// Only supports new guarantees for updates, does not work for aggregated guarantees (local / global) | ||
/// @param self The guarantee object to check | ||
/// @param price The oracle price to compare | ||
/// @return The price deviation of the guarantee from the oracle price | ||
function priceDeviation(Guarantee memory self, Fixed6 price) internal pure returns (UFixed6) { | ||
if (takerTotal(self).isZero()) return UFixed6Lib.ZERO; | ||
|
||
Fixed6 guarenteePrice = self.notional.div(taker(self)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: spelling |
||
return guarenteePrice.sub(price).div(guarenteePrice.min(price)).abs(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it safe to assume that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should not be possible for The Any reverts here would only block a fresh update, it wouldn't brick the settlement flywheel. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth adding a comment stating that, to avoid audit reports on the same. |
||
} | ||
|
||
/// @notice Updates the current global guarantee with a new local guarantee | ||
/// @param self The guarantee object to update | ||
/// @param guarantee The new guarantee | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,9 @@ struct MarketParameter { | |
/// @dev The maximum amount of orders that can be pending at one time per account | ||
uint256 maxPendingLocal; | ||
|
||
/// @dev The maximum deviation percentage from the oracle price that is allowed for an intent price override | ||
UFixed6 maxPriceDeviation; | ||
|
||
/// @dev Whether the market is in close-only mode | ||
bool closed; | ||
|
||
|
@@ -49,7 +52,8 @@ using MarketParameterStorageLib for MarketParameterStorage global; | |
/// uint24 riskFee; // <= 1677% | ||
/// uint16 maxPendingGlobal; // <= 65k | ||
/// uint16 maxPendingLocal; // <= 65k | ||
/// uint48 __unallocated__; // <= 281m | ||
/// uint24 maxPriceDeviation; // <= 16.77x | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
/// uint24 __unallocated__; | ||
/// uint8 flags; | ||
/// } | ||
/// | ||
|
@@ -60,7 +64,7 @@ library MarketParameterStorageLib { | |
function read(MarketParameterStorage storage self) internal view returns (MarketParameter memory) { | ||
uint256 slot0 = self.slot0; | ||
|
||
uint256 flags = uint256(slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 16 - 16 - 48 - 8)) >> (256 - 8); | ||
uint256 flags = uint256(slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 16 - 16 - 24 - 24 - 8)) >> (256 - 8); | ||
(bool closed, bool settle) = | ||
(flags & 0x04 == 0x04, flags & 0x08 == 0x08); | ||
|
||
|
@@ -70,8 +74,9 @@ library MarketParameterStorageLib { | |
UFixed6.wrap(uint256(slot0 << (256 - 24 - 24 - 24)) >> (256 - 24)), | ||
UFixed6.wrap(uint256(slot0 << (256 - 24 - 24 - 24 - 24)) >> (256 - 24)), | ||
UFixed6.wrap(uint256(slot0 << (256 - 24 - 24 - 24 - 24 - 24)) >> (256 - 24)), | ||
uint256(slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 16)) >> (256 - 16), | ||
uint256(slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 16 - 16)) >> (256 - 16), | ||
uint256(slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 16)) >> (256 - 16), | ||
uint256(slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 16 - 16)) >> (256 - 16), | ||
UFixed6.wrap(uint256(slot0 << (256 - 24 - 24 - 24 - 24 - 24 - 16 - 16 - 24)) >> (256 - 24)), | ||
closed, | ||
settle | ||
); | ||
|
@@ -94,6 +99,7 @@ library MarketParameterStorageLib { | |
|
||
if (newValue.maxPendingGlobal > uint256(type(uint16).max)) revert MarketParameterStorageInvalidError(); | ||
if (newValue.maxPendingLocal > uint256(type(uint16).max)) revert MarketParameterStorageInvalidError(); | ||
if (newValue.maxPriceDeviation.gt(UFixed6.wrap(type(uint24).max))) revert MarketParameterStorageInvalidError(); | ||
|
||
_store(self, newValue); | ||
} | ||
|
@@ -103,14 +109,15 @@ library MarketParameterStorageLib { | |
(newValue.settle ? 0x08 : 0x00); | ||
|
||
uint256 encoded0 = | ||
uint256(UFixed6.unwrap(newValue.fundingFee) << (256 - 24)) >> (256 - 24) | | ||
uint256(UFixed6.unwrap(newValue.interestFee) << (256 - 24)) >> (256 - 24 - 24) | | ||
uint256(UFixed6.unwrap(newValue.makerFee) << (256 - 24)) >> (256 - 24 - 24 - 24) | | ||
uint256(UFixed6.unwrap(newValue.takerFee) << (256 - 24)) >> (256 - 24 - 24 - 24 - 24) | | ||
uint256(UFixed6.unwrap(newValue.riskFee) << (256 - 24)) >> (256 - 24 - 24 - 24 - 24 - 24) | | ||
uint256(newValue.maxPendingGlobal << (256 - 16)) >> (256 - 24 - 24 - 24 - 24 - 24 - 16) | | ||
uint256(newValue.maxPendingLocal << (256 - 16)) >> (256 - 24 - 24 - 24 - 24 - 24 - 16 - 16) | | ||
uint256(flags << (256 - 8)) >> (256 - 24 - 24 - 24 - 24 - 24 - 16 - 16 - 48 - 8); | ||
uint256(UFixed6.unwrap(newValue.fundingFee) << (256 - 24)) >> (256 - 24) | | ||
uint256(UFixed6.unwrap(newValue.interestFee) << (256 - 24)) >> (256 - 24 - 24) | | ||
uint256(UFixed6.unwrap(newValue.makerFee) << (256 - 24)) >> (256 - 24 - 24 - 24) | | ||
uint256(UFixed6.unwrap(newValue.takerFee) << (256 - 24)) >> (256 - 24 - 24 - 24 - 24) | | ||
uint256(UFixed6.unwrap(newValue.riskFee) << (256 - 24)) >> (256 - 24 - 24 - 24 - 24 - 24) | | ||
uint256(newValue.maxPendingGlobal << (256 - 16)) >> (256 - 24 - 24 - 24 - 24 - 24 - 16) | | ||
uint256(newValue.maxPendingLocal << (256 - 16)) >> (256 - 24 - 24 - 24 - 24 - 24 - 16 - 16) | | ||
uint256(UFixed6.unwrap(newValue.maxPriceDeviation) << (256 - 24)) >> (256 - 24 - 24 - 24 - 24 - 24 - 16 - 16 - 24) | | ||
uint256(flags << (256 - 8)) >> (256 - 24 - 24 - 24 - 24 - 24 - 16 - 16 - 24 - 24 - 8); | ||
|
||
assembly { | ||
sstore(self.slot, encoded0) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use
taker(self)
here to correspond with the belowdiv
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
takerTotal
is more correct for measuring whether the guarantee is empty, since you can have an aggregated guarantee net to zero, but we need to usetaker
in the math below for the sign.