Skip to content

Commit

Permalink
Merge pull request #25 from uniswapfoundation/update-5-23
Browse files Browse the repository at this point in the history
Big update
  • Loading branch information
saucepoint authored May 31, 2024
2 parents 1bf8154 + 9ee5c9e commit d73984a
Show file tree
Hide file tree
Showing 45 changed files with 1,006 additions and 642 deletions.
2 changes: 1 addition & 1 deletion .forge-snapshots/autodynamic fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
242952
141494
2 changes: 1 addition & 1 deletion .forge-snapshots/hookFee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
265804
150527
2 changes: 1 addition & 1 deletion .forge-snapshots/manual dynamic fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
219217
122293
2 changes: 1 addition & 1 deletion forge-lib/v4-core
Submodule v4-core updated 236 files
20 changes: 12 additions & 8 deletions forge-test/Counter.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
pragma solidity ^0.8.24;

// import {BaseHook} from "v4-periphery/BaseHook.sol";
import {BaseHook} from "@v4-by-example/utils/BaseHook.sol";
import {BaseHook} from "v4-periphery/BaseHook.sol";

import {Hooks} from "v4-core/src/libraries/Hooks.sol";
import {IPoolManager} from "v4-core/src/interfaces/IPoolManager.sol";
import {PoolKey} from "v4-core/src/types/PoolKey.sol";
import {PoolId, PoolIdLibrary} from "v4-core/src/types/PoolId.sol";
import {BalanceDelta} from "v4-core/src/types/BalanceDelta.sol";
import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "v4-core/src/types/BeforeSwapDelta.sol";

contract Counter is BaseHook {
using PoolIdLibrary for PoolKey;
Expand Down Expand Up @@ -37,7 +37,11 @@ contract Counter is BaseHook {
beforeSwap: true,
afterSwap: true,
beforeDonate: false,
afterDonate: false
afterDonate: false,
beforeSwapReturnDelta: false,
afterSwapReturnDelta: false,
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}

Expand All @@ -48,19 +52,19 @@ contract Counter is BaseHook {
function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata, bytes calldata)
external
override
returns (bytes4)
returns (bytes4, BeforeSwapDelta, uint24)
{
beforeSwapCount[key.toId()]++;
return BaseHook.beforeSwap.selector;
return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0);
}

function afterSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata, BalanceDelta, bytes calldata)
external
override
returns (bytes4)
returns (bytes4, int128)
{
afterSwapCount[key.toId()]++;
return BaseHook.afterSwap.selector;
return (BaseHook.afterSwap.selector, 0);
}

function beforeAddLiquidity(
Expand Down
56 changes: 25 additions & 31 deletions forge-test/Counter.t.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
pragma solidity ^0.8.24;

import "forge-std/Test.sol";
import {IHooks} from "v4-core/src/interfaces/IHooks.sol";
Expand All @@ -10,22 +10,20 @@ import {PoolKey} from "v4-core/src/types/PoolKey.sol";
import {BalanceDelta} from "v4-core/src/types/BalanceDelta.sol";
import {PoolId, PoolIdLibrary} from "v4-core/src/types/PoolId.sol";
import {CurrencyLibrary, Currency} from "v4-core/src/types/Currency.sol";
import {PoolSwapTest} from "v4-core/src/test/PoolSwapTest.sol";
import {Deployers} from "v4-core/test/utils/Deployers.sol";
import {Counter} from "./Counter.sol";
import {HookMiner} from "./utils/HookMiner.sol";
import {GasSnapshot} from "forge-gas-snapshot/GasSnapshot.sol";
import {PoolSwapTest} from "v4-core/src/test/PoolSwapTest.sol";

contract CounterTest is Test, Deployers, GasSnapshot {
contract CounterTest is Test, Deployers {
using PoolIdLibrary for PoolKey;
using CurrencyLibrary for Currency;

Counter counter;
PoolKey poolKey;
PoolId poolId;

function setUp() public {
// creates the pool manager, test tokens, and other utility routers
// creates the pool manager, utility routers, and test tokens
Deployers.deployFreshManagerAndRouters();
Deployers.deployMintAndApprove2Currencies();

Expand All @@ -40,20 +38,18 @@ contract CounterTest is Test, Deployers, GasSnapshot {
require(address(counter) == hookAddress, "CounterTest: hook address mismatch");

// Create the pool
poolKey = PoolKey(currency0, currency1, 3000, 60, IHooks(address(counter)));
poolId = poolKey.toId();
manager.initialize(poolKey, SQRT_RATIO_1_1, ZERO_BYTES);
key = PoolKey(currency0, currency1, 3000, 60, IHooks(address(counter)));
poolId = key.toId();
manager.initialize(key, SQRT_PRICE_1_1, ZERO_BYTES);

// Provide liquidity to the pool
modifyLiquidityRouter.modifyLiquidity(key, IPoolManager.ModifyLiquidityParams(-60, 60, 10 ether, 0), ZERO_BYTES);
modifyLiquidityRouter.modifyLiquidity(
poolKey, IPoolManager.ModifyLiquidityParams(-60, 60, 10 ether), ZERO_BYTES
);
modifyLiquidityRouter.modifyLiquidity(
poolKey, IPoolManager.ModifyLiquidityParams(-120, 120, 10 ether), ZERO_BYTES
key, IPoolManager.ModifyLiquidityParams(-120, 120, 10 ether, 0), ZERO_BYTES
);
modifyLiquidityRouter.modifyLiquidity(
poolKey,
IPoolManager.ModifyLiquidityParams(TickMath.minUsableTick(60), TickMath.maxUsableTick(60), 10 ether),
key,
IPoolManager.ModifyLiquidityParams(TickMath.minUsableTick(60), TickMath.maxUsableTick(60), 10 ether, 0),
ZERO_BYTES
);
}
Expand All @@ -67,31 +63,29 @@ contract CounterTest is Test, Deployers, GasSnapshot {
assertEq(counter.afterSwapCount(poolId), 0);

// Perform a test swap //
int256 amount = -100;
bool zeroForOne = true;
BalanceDelta swapDelta = swap(poolKey, zeroForOne, amount, ZERO_BYTES);
int256 amountSpecified = -1e18; // negative number indicates exact input swap!
BalanceDelta swapDelta = swap(key, zeroForOne, amountSpecified, ZERO_BYTES);
// ------------------- //

assertEq(int256(swapDelta.amount0()), amount);
assertEq(int256(swapDelta.amount0()), amountSpecified);

assertEq(counter.beforeSwapCount(poolId), 1);
assertEq(counter.afterSwapCount(poolId), 1);
}

function test_counter_snapshot() public {
int256 amount = 1e18;
bool zeroForOne = true;
IPoolManager.SwapParams memory params = IPoolManager.SwapParams({
zeroForOne: zeroForOne,
amountSpecified: amount,
sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT // unlimited impact
});
function testLiquidityHooks() public {
// positions were created in setup()
assertEq(counter.beforeAddLiquidityCount(poolId), 3);
assertEq(counter.beforeRemoveLiquidityCount(poolId), 0);

PoolSwapTest.TestSettings memory testSettings =
PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true, currencyAlreadySent: false});
// remove liquidity
int256 liquidityDelta = -1e18;
modifyLiquidityRouter.modifyLiquidity(
key, IPoolManager.ModifyLiquidityParams(-60, 60, liquidityDelta, 0), ZERO_BYTES
);

snapStart("counter");
swapRouter.swap(poolKey, params, testSettings, ZERO_BYTES);
snapEnd();
assertEq(counter.beforeAddLiquidityCount(poolId), 3);
assertEq(counter.beforeRemoveLiquidityCount(poolId), 1);
}
}
53 changes: 27 additions & 26 deletions forge-test/CustomCurve.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import {BalanceDelta} from "v4-core/src/types/BalanceDelta.sol";
import {PoolId, PoolIdLibrary} from "v4-core/src/types/PoolId.sol";
import {CurrencyLibrary, Currency} from "v4-core/src/types/Currency.sol";
import {Deployers} from "v4-core/test/utils/Deployers.sol";
import {CustomCurve} from "@v4-by-example/pages/hooks/custom-curve/CustomCurve.sol";
import {ConstantSumCurve} from "@v4-by-example/pages/hooks/custom-curve/CustomCurve.sol";
import {HookMiner} from "./utils/HookMiner.sol";
import {IERC20} from "forge-std/interfaces/IERC20.sol";

contract CustomCurveTest is Test, Deployers {
using PoolIdLibrary for PoolKey;
using CurrencyLibrary for Currency;

CustomCurve hook;
ConstantSumCurve hook;
PoolKey poolKey;
PoolId poolId;

Expand All @@ -29,41 +29,42 @@ contract CustomCurveTest is Test, Deployers {
Deployers.deployMintAndApprove2Currencies();

// Deploy the hook to an address with the correct flags
uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG);
uint160 flags =
uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG);
(address hookAddress, bytes32 salt) =
HookMiner.find(address(this), flags, type(CustomCurve).creationCode, abi.encode(address(manager)));
hook = new CustomCurve{salt: salt}(IPoolManager(address(manager)));
HookMiner.find(address(this), flags, type(ConstantSumCurve).creationCode, abi.encode(address(manager)));
hook = new ConstantSumCurve{salt: salt}(IPoolManager(address(manager)));
require(address(hook) == hookAddress, "CustomCurveTest: hook address mismatch");

// Create the pool
poolKey = PoolKey(currency0, currency1, 3000, 60, IHooks(hook));
poolId = poolKey.toId();
manager.initialize(poolKey, SQRT_RATIO_1_1, ZERO_BYTES);
manager.initialize(poolKey, SQRT_PRICE_1_1, ZERO_BYTES);

PoolKey memory hookless = PoolKey(currency0, currency1, 3000, 60, IHooks(address(0x0)));
manager.initialize(hookless, SQRT_RATIO_1_1, ZERO_BYTES);

// add liquidity so theres tokens to take
modifyLiquidityRouter.modifyLiquidity(
hookless, IPoolManager.ModifyLiquidityParams(-60, 60, 10000 ether), ZERO_BYTES
);

// Provide liquidity to the pool
IERC20(Currency.unwrap(currency0)).transfer(address(hook), 10_000 ether);
IERC20(Currency.unwrap(currency1)).transfer(address(hook), 10_000 ether);
// Add liquidity
IERC20(Currency.unwrap(currency0)).approve(address(hook), type(uint256).max);
IERC20(Currency.unwrap(currency1)).approve(address(hook), type(uint256).max);
hook.addLiquidity(poolKey, 100 ether, 100 ether);
}

function test_swap() public {
uint256 token1Before = currency1.balanceOfSelf();

// Perform a test swap //
int256 amount = 10e18;
bool zeroForOne = true;
swap(poolKey, zeroForOne, amount, ZERO_BYTES);
// ------------------- //
function test_swap(bool zeroForOne, int256 amountSpecified) public {
amountSpecified = bound(amountSpecified, -100 ether, 100 ether);
vm.assume(amountSpecified != 0);

uint256 token0Before = currency0.balanceOfSelf();
uint256 token1Before = currency1.balanceOfSelf();
swap(poolKey, zeroForOne, amountSpecified, ZERO_BYTES);
uint256 token0After = currency0.balanceOfSelf();
uint256 token1After = currency1.balanceOfSelf();

assertEq(token1After - token1Before, 1e18);
bool exactInput = amountSpecified < 0;
uint256 amountSwapped = exactInput ? uint256(-amountSpecified) : uint256(amountSpecified);
if (zeroForOne) {
assertEq(token0Before - token0After, amountSwapped);
assertEq(token1After - token1Before, amountSwapped);
} else {
assertEq(token0After - token0Before, amountSwapped);
assertEq(token1Before - token1After, amountSwapped);
}
}
}
Loading

0 comments on commit d73984a

Please sign in to comment.