Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/OscillonHook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ contract OscillonHook is BaseHook {
address indexed newOwner
);

modifier onlyOwner() {
if (msg.sender != owner) revert NotOwner();
_;
}

// ── Governance ───────────────────────────────────────────────────────────

address public owner;
Expand All @@ -77,7 +82,7 @@ contract OscillonHook is BaseHook {
// ── Depeg thresholds (bps) ────────────────────────────────────────────────

uint256 public constant SMALL_DEPEG_BPS = 7;
uint256 public constant DRAIN_DEPEG_BPS = 20;
uint256 public constant DRAIN_DEPEG_BPS = 25;

/// @notice v2: no freeze at this threshold — fee just hits MAX_FEE_PIPS.
uint256 public constant SEVERE_DEPEG_BPS = 50;
Expand Down Expand Up @@ -362,6 +367,7 @@ contract OscillonHook is BaseHook {
bool inRestoreWindow = cfg.lastHighDepegAt != 0 &&
(block.timestamp - cfg.lastHighDepegAt) <= RESTORE_WINDOW;
// ── Healthy pool — no depeg ───────────────────────────────────────────

if (ctx.depegBps < SMALL_DEPEG_BPS) {
// If we are in the restore window (recently resolved depeg)
// and this is a restore-direction swap → discount
Expand All @@ -379,6 +385,7 @@ contract OscillonHook is BaseHook {
// Even during an active depeg, swaps going the "right" direction
// (buying the depegged token) get the restore discount.
// This attracts aggregator flow and helps pool rebalance naturally.

if (!ctx.isDrain) {
return RESTORE_FEE_PIPS;
}
Expand All @@ -389,7 +396,6 @@ contract OscillonHook is BaseHook {
// Instead: fee hits MAX_FEE_PIPS (50 bps) and stays there.
// Pool keeps running. Arb is expensive but not impossible.
// LPs protected by high cost. No permanently bricked pools.

if (ctx.depegBps >= SEVERE_DEPEG_BPS) {
fee = MAX_FEE_PIPS; // 50 bps — severe depeg cap
} else if (ctx.depegBps >= DRAIN_DEPEG_BPS) {
Expand Down Expand Up @@ -508,9 +514,4 @@ contract OscillonHook is BaseHook {
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}

modifier onlyOwner() {
if (msg.sender != owner) revert NotOwner();
_;
}
}
4 changes: 2 additions & 2 deletions test/OscillonHook.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ contract OscillonHookBasicTest is Test, Deployers {

function test_swap_WhenStableDropsTo089_UsesMaxFee() public {
// Depeg stable1 from $1.00 -> $0.89 (11% depeg = 1100 bps).
oracle1.updateAnswer(890000000000000000);
oracle1.updateAnswer(990000000000000000);

bool stable1IsCurrency0 = Currency.unwrap(poolKey.currency0) ==
address(stable1);
Expand All @@ -127,7 +127,7 @@ contract OscillonHookBasicTest is Test, Deployers {
: (TickMath.MAX_SQRT_PRICE - 1);

vm.expectEmit(true, false, false, true, address(hook));
emit DepegDetected(poolKey.toId(), 1100, MAX_FEE_PIPS, AMOUNT_IN, true);
emit DepegDetected(poolKey.toId(), 100, MAX_FEE_PIPS, AMOUNT_IN, true);

swapRouter.swap(
poolKey,
Expand Down
Loading