Skip to content

Commit

Permalink
Merge branch 'main' into optimization/BalanceDelta
Browse files Browse the repository at this point in the history
  • Loading branch information
chefburger committed May 30, 2024
2 parents 4dd78da + 2d34d36 commit ae7c6fe
Show file tree
Hide file tree
Showing 47 changed files with 206 additions and 447 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
136931
137028
Original file line number Diff line number Diff line change
@@ -1 +1 @@
32533
32545
Original file line number Diff line number Diff line change
@@ -1 +1 @@
146635
146756
Original file line number Diff line number Diff line change
@@ -1 +1 @@
294227
294324
2 changes: 1 addition & 1 deletion .forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
130141
130237
2 changes: 1 addition & 1 deletion .forge-snapshots/BinPoolManagerTest#testGasDonate.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
119261
119403
Original file line number Diff line number Diff line change
@@ -1 +1 @@
975902
976020
Original file line number Diff line number Diff line change
@@ -1 +1 @@
338092
338210
Original file line number Diff line number Diff line change
@@ -1 +1 @@
341673
341791
Original file line number Diff line number Diff line change
@@ -1 +1 @@
144616
144734
Original file line number Diff line number Diff line change
@@ -1 +1 @@
179041
179149
Original file line number Diff line number Diff line change
@@ -1 +1 @@
185024
185132
Original file line number Diff line number Diff line change
@@ -1 +1 @@
137479
137587
Original file line number Diff line number Diff line change
@@ -1 +1 @@
308185
308270
Original file line number Diff line number Diff line change
@@ -1 +1 @@
360013
360096
Original file line number Diff line number Diff line change
@@ -1 +1 @@
175181
175264
Original file line number Diff line number Diff line change
@@ -1 +1 @@
245159
245205
2 changes: 1 addition & 1 deletion .forge-snapshots/CLPoolManagerTest#donateBothTokens.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
168435
168507
2 changes: 1 addition & 1 deletion .forge-snapshots/CLPoolManagerTest#gasDonateOneToken.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
112267
112314
Original file line number Diff line number Diff line change
@@ -1 +1 @@
121284
121359
Original file line number Diff line number Diff line change
@@ -1 +1 @@
138632
138739
Original file line number Diff line number Diff line change
@@ -1 +1 @@
172143
172226
Original file line number Diff line number Diff line change
@@ -1 +1 @@
158546
158653
2 changes: 1 addition & 1 deletion .forge-snapshots/CLPoolManagerTest#swap_simple.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
76575
76594
Original file line number Diff line number Diff line change
@@ -1 +1 @@
150789
150915
2 changes: 1 addition & 1 deletion .forge-snapshots/CLPoolManagerTest#swap_withHooks.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
93467
93486
2 changes: 1 addition & 1 deletion .forge-snapshots/CLPoolManagerTest#swap_withNative.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
76578
76597
1 change: 1 addition & 0 deletions src/types/Currency.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {IERC20Minimal} from "../interfaces/IERC20Minimal.sol";
type Currency is address;

using {greaterThan as >, lessThan as <, greaterThanOrEqualTo as >=, equals as ==} for Currency global;
using CurrencyLibrary for Currency global;

function equals(Currency currency, Currency other) pure returns (bool) {
return Currency.unwrap(currency) == Currency.unwrap(other);
Expand Down
44 changes: 44 additions & 0 deletions test/helpers/CurrencySettlement.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright (C) 2024 PancakeSwap
pragma solidity ^0.8.24;

import {Currency} from "../../src/types/Currency.sol";
import {IVault} from "../../src/interfaces/IVault.sol";
import {IERC20Minimal} from "../../src/interfaces/IERC20Minimal.sol";

/// @notice Helper library for currency settlement
/// @dev It is advised to consider referencing this library for currency settlement
library CurrencySettlement {
/// @notice Settle (pay) a currency to vault
/// @param currency Currency to settle
/// @param vault Vault address
/// @param payer Address of the payer, the token sender
/// @param amount Amount to send
/// @param burn If true, burn the VaultToken obtained by vault.mint() earlier, otherwise ERC20-transfer to vault
function settle(Currency currency, IVault vault, address payer, uint256 amount, bool burn) internal {
// for native currencies or burns, calling sync is not required
if (burn) {
vault.burn(payer, currency, amount);
} else if (currency.isNative()) {
vault.settle{value: amount}(currency);
} else {
vault.sync(currency);
if (payer != address(this)) {
IERC20Minimal(Currency.unwrap(currency)).transferFrom(payer, address(vault), amount);
} else {
IERC20Minimal(Currency.unwrap(currency)).transfer(address(vault), amount);
}
vault.settle(currency);
}
}

/// @notice Take (receive) a currency from vault
/// @param currency Currency to take
/// @param vault Vault address
/// @param recipient Address of the recipient, the token receiver
/// @param amount Amount to receive
/// @param claims If true, mint VaultToken, otherwise ERC20-transfer from the vault to recipient
function take(Currency currency, IVault vault, address recipient, uint256 amount, bool claims) internal {
claims ? vault.mint(recipient, currency, amount) : vault.take(currency, recipient, amount);
}
}
1 change: 0 additions & 1 deletion test/libraries/Currency.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {Currency, CurrencyLibrary} from "../../src/types/Currency.sol";
import {TokenRejecter} from "../helpers/TokenRejecter.sol";

contract TestCurrency is Test {
using CurrencyLibrary for Currency;
using CurrencyLibrary for uint256;

uint256 constant initialERC20Balance = 1000 ether;
Expand Down
24 changes: 4 additions & 20 deletions test/pool-bin/helpers/BinDonateHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import {IBinPoolManager} from "../../../src/pool-bin/interfaces/IBinPoolManager.
import {BalanceDelta} from "../../../src/types/BalanceDelta.sol";
import {CurrencyLibrary, Currency} from "../../../src/types/Currency.sol";
import {PoolKey} from "../../../src/types/PoolKey.sol";
import {CurrencySettlement} from "../../helpers/CurrencySettlement.sol";

contract BinDonateHelper {
using CurrencyLibrary for Currency;
using CurrencySettlement for Currency;

IBinPoolManager public immutable binManager;
IVault public immutable vault;
Expand Down Expand Up @@ -50,25 +51,8 @@ contract BinDonateHelper {

(BalanceDelta delta,) = binManager.donate(data.key, data.amount0, data.amount1, data.hookData);

if (delta.amount0() < 0) {
if (key.currency0.isNative()) {
vault.settle{value: uint128(-delta.amount0())}(key.currency0);
} else {
vault.sync(key.currency0);
IERC20(Currency.unwrap(key.currency0)).transferFrom(sender, address(vault), uint128(-delta.amount0()));
vault.settle(key.currency0);
}
}

if (delta.amount1() < 0) {
if (key.currency1.isNative()) {
vault.settle{value: uint128(-delta.amount1())}(key.currency1);
} else {
vault.sync(key.currency1);
IERC20(Currency.unwrap(key.currency1)).transferFrom(sender, address(vault), uint128(-delta.amount1()));
vault.settle(key.currency1);
}
}
if (delta.amount0() < 0) key.currency0.settle(vault, sender, uint128(-delta.amount0()), false);
if (delta.amount1() < 0) key.currency1.settle(vault, sender, uint128(-delta.amount1()), false);

return abi.encode(delta);
}
Expand Down
35 changes: 7 additions & 28 deletions test/pool-bin/helpers/BinLiquidityHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IVault} from "../../../src/interfaces/IVault.sol";
import {IBinPoolManager} from "../../../src/pool-bin/interfaces/IBinPoolManager.sol";
import {BalanceDelta, BalanceDeltaLibrary} from "../../../src/types/BalanceDelta.sol";
import {CurrencyLibrary, Currency} from "../../../src/types/Currency.sol";
import {Currency} from "../../../src/types/Currency.sol";
import {PoolKey} from "../../../src/types/PoolKey.sol";
import {Hooks} from "../../../src/libraries/Hooks.sol";
import {CurrencySettlement} from "../../helpers/CurrencySettlement.sol";

contract BinLiquidityHelper {
using CurrencyLibrary for Currency;
using CurrencySettlement for Currency;
using Hooks for bytes32;

error HookMissingNoOpPermission();
Expand Down Expand Up @@ -85,32 +86,10 @@ contract BinLiquidityHelper {
(delta,) = binManager.mint(data.key, data.params, data.hookData);
}

if (delta.amount0() < 0) {
if (key.currency0.isNative()) {
vault.settle{value: uint128(-delta.amount0())}(key.currency0);
} else {
vault.sync(key.currency0);
IERC20(Currency.unwrap(key.currency0)).transferFrom(sender, address(vault), uint128(-delta.amount0()));
vault.settle(key.currency0);
}
}

if (delta.amount1() < 0) {
if (key.currency1.isNative()) {
vault.settle{value: uint128(-delta.amount1())}(key.currency1);
} else {
vault.sync(key.currency1);
IERC20(Currency.unwrap(key.currency1)).transferFrom(sender, address(vault), uint128(-delta.amount1()));
vault.settle(key.currency1);
}
}

if (delta.amount0() > 0) {
vault.take(key.currency0, sender, uint128(delta.amount0()));
}
if (delta.amount1() > 0) {
vault.take(key.currency1, sender, uint128(delta.amount1()));
}
if (delta.amount0() < 0) key.currency0.settle(vault, sender, uint128(-delta.amount0()), false);
if (delta.amount0() > 0) key.currency0.take(vault, sender, uint128(delta.amount0()), false);
if (delta.amount1() < 0) key.currency1.settle(vault, sender, uint128(-delta.amount1()), false);
if (delta.amount1() > 0) key.currency1.take(vault, sender, uint128(delta.amount1()), false);

return abi.encode(delta);
}
Expand Down
59 changes: 23 additions & 36 deletions test/pool-bin/helpers/BinReturnsDeltaHook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import {IVault} from "../../../src/interfaces/IVault.sol";
import {Hooks} from "../../../src/libraries/Hooks.sol";
import {IBinPoolManager} from "../../../src/pool-bin/interfaces/IBinPoolManager.sol";
import {PoolKey} from "../../../src/types/PoolKey.sol";
import {Currency, CurrencyLibrary} from "../../../src/types/Currency.sol";
import {Currency} from "../../../src/types/Currency.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {toBalanceDelta, BalanceDelta, BalanceDeltaLibrary} from "../../../src/types/BalanceDelta.sol";
import {BeforeSwapDelta, toBeforeSwapDelta} from "../../../src/types/BeforeSwapDelta.sol";
import {BaseBinTestHook} from "./BaseBinTestHook.sol";
import {CurrencySettlement} from "../../helpers/CurrencySettlement.sol";

contract BinReturnsDeltaHook is BaseBinTestHook {
error InvalidAction();

using CurrencyLibrary for Currency;
using CurrencySettlement for Currency;
using Hooks for bytes32;

IVault public immutable vault;
Expand Down Expand Up @@ -94,37 +95,25 @@ contract BinReturnsDeltaHook is BaseBinTestHook {

if (swapForY) {
// the specified token is token0
if (hookDeltaSpecified < 0) {
vault.sync(key.currency0);
key.currency0.transfer(address(vault), uint128(-hookDeltaSpecified));
vault.settle(key.currency0);
} else {
vault.take(key.currency0, address(this), uint128(hookDeltaSpecified));
}
if (hookDeltaSpecified < 0) key.currency0.settle(vault, address(this), uint128(-hookDeltaSpecified), false);
if (hookDeltaSpecified > 0) key.currency0.take(vault, address(this), uint128(hookDeltaSpecified), false);

if (hookDeltaUnspecified < 0) {
vault.sync(key.currency1);
key.currency1.transfer(address(vault), uint128(-hookDeltaUnspecified));
vault.settle(key.currency1);
} else {
vault.take(key.currency1, address(this), uint128(hookDeltaUnspecified));
key.currency1.settle(vault, address(this), uint128(-hookDeltaUnspecified), false);
}
if (hookDeltaUnspecified > 0) {
key.currency1.take(vault, address(this), uint128(hookDeltaUnspecified), false);
}
} else {
// the specified token is token1
if (hookDeltaSpecified < 0) {
vault.sync(key.currency1);
key.currency1.transfer(address(vault), uint128(-hookDeltaSpecified));
vault.settle(key.currency1);
} else {
vault.take(key.currency1, address(this), uint128(hookDeltaSpecified));
}
if (hookDeltaSpecified < 0) key.currency1.settle(vault, address(this), uint128(-hookDeltaSpecified), false);
if (hookDeltaSpecified > 0) key.currency1.take(vault, address(this), uint128(hookDeltaSpecified), false);

if (hookDeltaUnspecified < 0) {
vault.sync(key.currency0);
key.currency0.transfer(address(vault), uint128(-hookDeltaUnspecified));
vault.settle(key.currency0);
} else {
vault.take(key.currency0, address(this), uint128(hookDeltaUnspecified));
key.currency0.settle(vault, address(this), uint128(-hookDeltaUnspecified), false);
}
if (hookDeltaUnspecified > 0) {
key.currency0.take(vault, address(this), uint128(hookDeltaUnspecified), false);
}
}

Expand All @@ -145,20 +134,18 @@ contract BinReturnsDeltaHook is BaseBinTestHook {
if (swapForY) {
// the unspecified token is token1
if (hookDeltaUnspecified < 0) {
vault.sync(key.currency1);
key.currency1.transfer(address(vault), uint128(-hookDeltaUnspecified));
vault.settle(key.currency1);
} else {
vault.take(key.currency1, address(this), uint128(hookDeltaUnspecified));
key.currency1.settle(vault, address(this), uint128(-hookDeltaUnspecified), false);
}
if (hookDeltaUnspecified > 0) {
key.currency1.take(vault, address(this), uint128(hookDeltaUnspecified), false);
}
} else {
// the unspecified token is token0
if (hookDeltaUnspecified < 0) {
vault.sync(key.currency0);
key.currency0.transfer(address(vault), uint128(-hookDeltaUnspecified));
vault.settle(key.currency0);
} else {
vault.take(key.currency0, address(this), uint128(hookDeltaUnspecified));
key.currency0.settle(vault, address(this), uint128(-hookDeltaUnspecified), false);
}
if (hookDeltaUnspecified > 0) {
key.currency0.take(vault, address(this), uint128(hookDeltaUnspecified), false);
}
}

Expand Down
Loading

0 comments on commit ae7c6fe

Please sign in to comment.