Skip to content

Commit

Permalink
Allow perp cap to be adjustable
Browse files Browse the repository at this point in the history
  • Loading branch information
0xdomrom committed Nov 9, 2023
1 parent f21f3e1 commit 902da7d
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 8 deletions.
18 changes: 12 additions & 6 deletions src/feeds/LyraSpotDiffFeed.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ contract LyraSpotDiffFeed is BaseLyraFeed, ILyraSpotDiffFeed, ISpotDiffFeed {

ISpotFeed public spotFeed;
/// @dev spotDiffCap Cap the value returned based on a percentage of the spot price
int public constant SPOT_DIFF_CAP = 1.1e18;
int public spotDiffCap = 0.1e18;

SpotDiffDetail public spotDiffDetails;

Expand All @@ -49,6 +49,12 @@ contract LyraSpotDiffFeed is BaseLyraFeed, ILyraSpotDiffFeed, ISpotDiffFeed {
emit SpotFeedUpdated(_spotFeed);
}

function setSpotDiffCap(uint _spotDiffCap) external onlyOwner {
if (_spotDiffCap > 1e18) revert LSDF_InvalidSpotDiffCap();
spotDiffCap = SafeCast.toInt256(_spotDiffCap);
emit SpotDiffCapUpdated(_spotDiffCap);
}

////////////////////////
// Public Functions //
////////////////////////
Expand All @@ -64,12 +70,12 @@ contract LyraSpotDiffFeed is BaseLyraFeed, ILyraSpotDiffFeed, ISpotDiffFeed {
_checkNotStale(diffDetails.timestamp);

int spotDiff = int(diffDetails.spotDiff);
int res = spotInt + spotDiff;

if (spotDiff > 0) {
res = SignedMath.min(res, spotInt.multiplyDecimal(SPOT_DIFF_CAP));
int maxDiff = spotInt.multiplyDecimal(spotDiffCap);
int res = spotInt;
if (spotDiff >= 0) {
res += SignedMath.min(spotDiff, maxDiff);
} else {
res = SignedMath.max(res, spotInt.divideDecimal(SPOT_DIFF_CAP));
res += SignedMath.max(spotDiff, -maxDiff);
}

return (SafeCast.toUint256(res), Math.min(spotConfidence, diffDetails.confidence));
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces/ILyraSpotDiffFeed.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ interface ILyraSpotDiffFeed is IBaseLyraFeed {
// Events //
////////////////////////
event SpotFeedUpdated(ISpotFeed spotFeed);
event SpotDiffCapUpdated(uint spotDiffCap);
event SpotDiffUpdated(int96 spotDiff, uint96 confidence, uint64 timestamp);

////////////////////////
// Errors //
////////////////////////
error LSDF_InvalidSpotDiffCap();
error LSDF_InvalidConfidence();
}
51 changes: 49 additions & 2 deletions test/feed/unit-tests/LyraSpotDiffFeed.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ contract UNIT_LyraSpotDiffFeed is LyraFeedTestUtils {
feed.acceptData(_signFeedData(feed, pk, feedData));
(uint res,) = feed.getResult();
// res is capped at spot - 10%
assertEq(res, 990e18 * 1e18 / 1.1e18);
assertEq(res, 990e18 * 0.9e18 / 1e18);

vm.warp(block.timestamp + 1);

Expand All @@ -74,7 +74,7 @@ contract UNIT_LyraSpotDiffFeed is LyraFeedTestUtils {

(res,) = feed.getResult();
// res is capped at spot - 10%
assertEq(res, 990e18 * 1e18 / 1.1e18);
assertEq(res, 990e18 * 0.9e18 / 1e18);

vm.warp(block.timestamp + 1);

Expand All @@ -87,6 +87,53 @@ contract UNIT_LyraSpotDiffFeed is LyraFeedTestUtils {
assertEq(res, 990e18 * 1.1e18 / 1e18);
}

function testCanUpdateSpotDiffCap() public {
// make sure the value returned is always == spot
feed.setSpotDiffCap(0);

IBaseLyraFeed.FeedData memory feedData = _getDefaultSpotDiffData();

// if 0 is expected, return the capped value
feedData.data = abi.encode(-990e18, 1e18);
feedData.timestamp = uint64(block.timestamp);
feed.acceptData(_signFeedData(feed, pk, feedData));
(uint res,) = feed.getResult();
// res is capped at spot, so diff is ignored
assertEq(res, 990e18);

// now 50% diff cap
feed.setSpotDiffCap(0.5e18);
(res,) = feed.getResult();
assertEq(res, 495e18);

// now 100% diff cap
feed.setSpotDiffCap(1e18);
(res,) = feed.getResult();
assertEq(res, 0, "b");

// cannot set cap beyond 100%
vm.expectRevert(ILyraSpotDiffFeed.LSDF_InvalidSpotDiffCap.selector);
feed.setSpotDiffCap(1.1e18);

vm.warp(block.timestamp + 1);

// also works for a positive result
feedData.data = abi.encode(1000e18, 1e18);
feedData.timestamp = uint64(block.timestamp);
feed.acceptData(_signFeedData(feed, pk, feedData));
(res,) = feed.getResult();
// res is capped at spot * 2, even though diff exceeds that
assertEq(res, 1980e18);

feed.setSpotDiffCap(0.5e18);
(res,) = feed.getResult();
assertEq(res, 1485e18);

feed.setSpotDiffCap(0);
(res,) = feed.getResult();
assertEq(res, 990e18);
}

function testCannotUpdateSpotDiffFeedFromInvalidSigner() public {
// we didn't whitelist the pk owner this time
feed.addSigner(pkOwner, false);
Expand Down

0 comments on commit 902da7d

Please sign in to comment.