Skip to content

Commit

Permalink
Add docs for general hooks (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
cairoeth authored Nov 26, 2024
2 parents 471daa5 + 8b6651e commit 5919b57
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/base/BaseCustomAccounting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ abstract contract BaseCustomAccounting is BaseHook {
constructor(IPoolManager _poolManager) BaseHook(_poolManager) {}

/**
* @dev Call the custom swap logic and create a return delta to be consumed by the {PoolManager}.
* @dev Call the custom swap logic and create a return delta to be consumed by the `PoolManager`.
*/
function _beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata)
internal
Expand Down Expand Up @@ -72,7 +72,7 @@ abstract contract BaseCustomAccounting is BaseHook {
returns (uint256 amount);

/**
* @dev Set the hook permissions, specifically {beforeAddLiquidity}, {beforeSwap} and {beforeSwapReturnDelta}.
* @dev Set the hook permissions, specifically `beforeSwap` and `beforeSwapReturnDelta`.
*/
function getHookPermissions() public pure virtual override returns (Hooks.Permissions memory) {
return Hooks.Permissions({
Expand Down
4 changes: 2 additions & 2 deletions src/base/BaseCustomCurve.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {CurrencySettler} from "v4-core/test/utils/CurrencySettler.sol";
* v3-like concentrated liquidity implementation of Uniswap. By inheriting {BaseCustomAccounting}, the hook calls
* the {_getAmountOutFromExactInput} or {_getAmountInForExactOutput} function to calculate the amount of tokens
* to be taken or settled, and a return delta is created based on their outputs. This return delta is then
* consumed by the {PoolManager}.
* consumed by the `PoolManager`.
*
* IMPORTANT: This base contract acts similarly to {BaseNoOp}, which means that the hook must hold the liquidity
* for swaps.
Expand Down Expand Up @@ -83,7 +83,7 @@ abstract contract BaseCustomCurve is BaseCustomAccounting {
returns (uint256 amountIn);

/**
* @dev Set the hook permissions, specifically {beforeAddLiquidity}, {beforeSwap} and {beforeSwapReturnDelta}.
* @dev Set the hook permissions, specifically `beforeAddLiquidity`, `beforeSwap` and `beforeSwapReturnDelta`.
*/
function getHookPermissions() public pure virtual override returns (Hooks.Permissions memory) {
return Hooks.Permissions({
Expand Down
4 changes: 2 additions & 2 deletions src/base/BaseNoOp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {SafeCast} from "v4-core/src/libraries/SafeCast.sol";
/**
* @dev Base implementation for no-op hooks.
*
* IMPORTANT: Given that this contract overrides default logic of the {PoolManager}, liquidity
* IMPORTANT: Given that this contract overrides default logic of the `PoolManager`, liquidity
* must be provided by the hook itself (i.e. the hook must hold the liquidity/tokens).
*
* _Available since v0.1.0_
Expand Down Expand Up @@ -45,7 +45,7 @@ abstract contract BaseNoOp is BaseHook {
}

/**
* @dev Set the hook permissions, specifically {beforeSwap} and {beforeSwapReturnDelta}.
* @dev Set the hook permissions, specifically `beforeSwap` and `beforeSwapReturnDelta`.
*/
function getHookPermissions() public pure virtual override returns (Hooks.Permissions memory) {
return Hooks.Permissions({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Uniswap Hooks (last updated v0.1.0) (src/examples/AntiSandwichHook.sol)
// OpenZeppelin Uniswap Hooks (last updated v0.1.0) (src/general/AntiSandwichHook.sol)

pragma solidity ^0.8.20;

Expand All @@ -15,9 +15,23 @@ import {Slot0} from "v4-core/src/types/Slot0.sol";
import {StateLibrary} from "v4-core/src/libraries/StateLibrary.sol";

/**
* @dev Implementation of an anti-sandwich hook.
* @dev Sandwich-resistant hook, based on
* https://github.com/cairoeth/sandwich-resistant-hook/blob/master/src/srHook.sol[this]
* implementation.
*
* Based on the https://github.com/cairoeth/sandwich-resistant-hook/blob/master/src/srHook.sol[implementation by cairoeth].
* This hook implements the sandwich-resistant AMM design introduced
* https://www.umbraresearch.xyz/writings/sandwich-resistant-amm[here]. Specifically,
* this hook guarantees that no swaps get filled at a price better than the price at
* the beginning of the slot window (i.e. one block).
*
* Within a slot window, swaps impact the pool asymmetrically for buys and sells.
* When a buy order is executed, the offer on the pool increases in accordance with
* the xy=k curve. However, the bid price remains constant, instead increasing the
* amount of liquidity on the bid. Subsequent sells eat into this liquidity, while
* decreasing the offer price according to xy=k.
*
* NOTE: Swaps in the other direction do not get the positive price difference
* compared to the initial price before the first block swap.
*
* _Available since v0.1.0_
*/
Expand Down
12 changes: 12 additions & 0 deletions src/general/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
= General

[.readme-notice]
NOTE: This document is better viewed on the docs page.

Ready-to-use hooks built on top of the base and fee abstract contracts

* {AntiSandwichHook}: Hook resistant to atomic sandwich attacks

== Hooks

{{AntiSandwichHook}}
4 changes: 2 additions & 2 deletions test/examples/AntiSandwichHook.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.20;

import {Test} from "forge-std/Test.sol";
import {Deployers} from "v4-core/test/utils/Deployers.sol";
import {AntiSandwichHook} from "src/examples/AntiSandwichHook.sol";
import {AntiSandwichHook} from "src/general/AntiSandwichHook.sol";
import {IHooks} from "v4-core/src/interfaces/IHooks.sol";
import {Hooks} from "v4-core/src/libraries/Hooks.sol";
import {PoolSwapTest} from "v4-core/src/test/PoolSwapTest.sol";
Expand All @@ -24,7 +24,7 @@ contract AntiSandwichHookTest is Test, Deployers {
hook = AntiSandwichHook(
address(uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.AFTER_SWAP_FLAG | Hooks.AFTER_SWAP_RETURNS_DELTA_FLAG))
);
deployCodeTo("src/examples/AntiSandwichHook.sol:AntiSandwichHook", abi.encode(manager), address(hook));
deployCodeTo("src/general/AntiSandwichHook.sol:AntiSandwichHook", abi.encode(manager), address(hook));

(key,) = initPoolAndAddLiquidity(
currency0, currency1, IHooks(address(hook)), LPFeeLibrary.DYNAMIC_FEE_FLAG, SQRT_PRICE_1_1
Expand Down

0 comments on commit 5919b57

Please sign in to comment.