Skip to content

Commit

Permalink
feat: include more detail to make it concrete
Browse files Browse the repository at this point in the history
  • Loading branch information
ChefMist committed Nov 5, 2024
1 parent c490cab commit 93c949f
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 9 deletions.
3 changes: 0 additions & 3 deletions src/Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,6 @@ contract Vault is IVault, VaultToken, Ownable {

/// @dev optimization: msg.sender will always be app address, verification should be done on caller address
if (delta >= 0) {
console2.log("before deduct from reservesOfApp");
console2.log("reservesOfApp[msg.sender][currency]", reservesOfApp[msg.sender][currency]);
console2.log("delta", uint128(delta));
/// @dev arithmetic underflow make sure trader can't withdraw too much from app
reservesOfApp[msg.sender][currency] -= uint128(delta);
} else {
Expand Down
5 changes: 5 additions & 0 deletions src/pool-bin/BinPoolManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import {BeforeSwapDelta} from "../types/BeforeSwapDelta.sol";
import "./interfaces/IBinHooks.sol";
import {BinSlot0} from "./types/BinSlot0.sol";

import {console2} from "forge-std/console2.sol";

/// @notice Holds the state for all bin pools
contract BinPoolManager is IBinPoolManager, ProtocolFees, Extsload {
using BinPool for *;
Expand Down Expand Up @@ -193,10 +195,13 @@ contract BinPoolManager is IBinPoolManager, ProtocolFees, Extsload {
int128 delta0 = delta.amount0();
int128 delta1 = delta.amount1();

// positive deduct reservesOfApp
if (delta0 < 0) {
/// @dev account for delta0 first so reserveOfApp will be positive, then deduct hookDelta if required
vault.accountAppBalanceDelta(key.currency0, delta0, msg.sender);
if (hookDelta0 != 0) vault.accountAppBalanceDelta(key.currency0, hookDelta0, address(key.hooks));
} else {
/// @dev account for hookDelta0 first
if (hookDelta0 != 0) vault.accountAppBalanceDelta(key.currency0, hookDelta0, address(key.hooks));
if (delta0 != 0) vault.accountAppBalanceDelta(key.currency0, delta0, msg.sender);
}
Expand Down
54 changes: 50 additions & 4 deletions test/pool-bin/BinReturnsDeltaOverwriteSwap.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {BinLiquidityHelper} from "./helpers/BinLiquidityHelper.sol";
import {BinTestHelper} from "./helpers/BinTestHelper.sol";
import {Hooks} from "../../src/libraries/Hooks.sol";
import {BinReturnsDeltaHookOverwriteSwap} from "./helpers/BinReturnsDeltaHookOverwriteSwap.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract BinReturnsDeltaOverwriteSwap is Test, GasSnapshot, BinTestHelper {
using SafeCast for uint256;
Expand Down Expand Up @@ -86,19 +87,64 @@ contract BinReturnsDeltaOverwriteSwap is Test, GasSnapshot, BinTestHelper {
parameters: bytes32(uint256(binReturnsDeltaHookOverwriteSwap.getHooksRegistrationBitmap())).setBinStep(10)
});

binReturnsDeltaHookOverwriteSwap.setPoolKey(key);

poolManager.initialize(key, activeId);
}

function testSwap_xx() external {
// assume liquidity added via hook and sent to the vault
token0.mint(address(vault), 100 ether);
token1.mint(address(vault), 100 ether);
// token0.mint(address(vault), 100 ether);
// token1.mint(address(vault), 100 ether);

// assume hook has some liqudiity from earlier add liqudiity
token0.mint(address(binReturnsDeltaHookOverwriteSwap), 100 ether);
token1.mint(address(binReturnsDeltaHookOverwriteSwap), 100 ether);
// token0.mint(address(binReturnsDeltaHookOverwriteSwap), 100 ether);
// token1.mint(address(binReturnsDeltaHookOverwriteSwap), 100 ether);

address hAddr = address(binReturnsDeltaHookOverwriteSwap);

token0.mint(address(this), 10 ether);
token1.mint(address(this), 10 ether);

console2.log("---------start of testSwap_xx add liquidity----------------------");
console2.log(" balanceof user t0: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(this)) / 1 ether);
console2.log(" balanceof user t1: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(this)) / 1 ether);
console2.log(" balanceof user hAddr: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(hAddr)) / 1 ether);
console2.log(" balanceof user hAddr: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(hAddr)) / 1 ether);
console2.log(" balanceof user vault: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(vault)) / 1 ether);
console2.log(" balanceof user vault: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(vault)) / 1 ether);
console2.log("-------------------------------");

binReturnsDeltaHookOverwriteSwap.addLiquidity(1 ether, 1 ether);

console2.log("---------end of testSwap_xx add liquidity ----------------------");
console2.log(" balanceof user t0: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(this)) / 1 ether);
console2.log(" balanceof user t1: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(this)) / 1 ether);
console2.log(" balanceof user hAddr: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(hAddr)) / 1 ether);
console2.log(" balanceof user hAddr: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(hAddr)) / 1 ether);
console2.log(" balanceof user vault: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(vault)) / 1 ether);
console2.log(" balanceof user vault: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(vault)) / 1 ether);
console2.log("-------------------------------");

console2.log("---------start of testSwap_xx swap----------------------");
console2.log(" reserveOfApp t0 (ethers)", vault.reservesOfApp(address(poolManager), key.currency0) / 1 ether);
console2.log(" reserveOfApp t1 (ethers)", vault.reservesOfApp(address(poolManager), key.currency1) / 1 ether);
console2.log(" balanceof user t0: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(this)) / 1 ether);
console2.log(" balanceof user t1: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(this)) / 1 ether);
console2.log(" balanceof user hAddr: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(hAddr)) / 1 ether);
console2.log(" balanceof user hAddr: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(hAddr)) / 1 ether);
console2.log("-------------------------------");

BalanceDelta delta = binSwapHelper.swap(key, true, -int128(1 ether), BinSwapHelper.TestSettings(true, true), "");

console2.log("---------end of testSwap_xx swap----------------------");
console2.log(" reserveOfApp t0 (ethers)", vault.reservesOfApp(address(poolManager), key.currency0) / 1 ether);
console2.log(" reserveOfApp t1 (ethers)", vault.reservesOfApp(address(poolManager), key.currency1) / 1 ether);
console2.log(" balanceof user t0: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(this)) / 1 ether);
console2.log(" balanceof user t1: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(this)) / 1 ether);
console2.log(" balanceof user hAddr: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(hAddr)) / 1 ether);
console2.log(" balanceof user hAddr: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(hAddr)) / 1 ether);
console2.log("-------------------------------");
}

function testFuzz_Swap_xx(bool swapForY, uint256 swapAmount, bool exactInput) external {
Expand Down
33 changes: 31 additions & 2 deletions test/pool-bin/helpers/BinReturnsDeltaHookOverwriteSwap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import {toBalanceDelta, BalanceDelta, BalanceDeltaLibrary} from "../../../src/ty
import {BeforeSwapDelta, toBeforeSwapDelta} from "../../../src/types/BeforeSwapDelta.sol";
import {BaseBinTestHook} from "./BaseBinTestHook.sol";
import {CurrencySettlement} from "../../helpers/CurrencySettlement.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import {console2} from "forge-std/console2.sol";

contract BinReturnsDeltaHookOverwriteSwap is BaseBinTestHook {
error InvalidAction();
Expand All @@ -20,12 +23,17 @@ contract BinReturnsDeltaHookOverwriteSwap is BaseBinTestHook {

IVault public immutable vault;
IBinPoolManager public immutable poolManager;
PoolKey key;

constructor(IVault _vault, IBinPoolManager _poolManager) {
vault = _vault;
poolManager = _poolManager;
}

function setPoolKey(PoolKey memory _poolKey) external {
key = _poolKey;
}

function getHooksRegistrationBitmap() external pure override returns (uint16) {
return _hooksRegistrationBitmapFrom(
Permissions({
Expand All @@ -47,6 +55,27 @@ contract BinReturnsDeltaHookOverwriteSwap is BaseBinTestHook {
);
}

function addLiquidity(uint256 amt0, uint256 amt1) public {
// do any logic

// 1. Take input currency and amount from user
IERC20(Currency.unwrap(key.currency0)).transferFrom(msg.sender, address(this), amt0);
IERC20(Currency.unwrap(key.currency1)).transferFrom(msg.sender, address(this), amt1);

// 2. Mint -- so vault has token balance
vault.lock(abi.encode(amt0, amt1));
}

function lockAcquired(bytes calldata callbackData) external returns (bytes memory) {
(uint256 amt0, uint256 amt1) = abi.decode(callbackData, (uint256, uint256));

vault.mint(address(this), key.currency0, amt0);
key.currency0.settle(vault, address(this), amt0, false);

vault.mint(address(this), key.currency1, amt1);
key.currency1.settle(vault, address(this), amt1, false);
}

function beforeSwap(address, PoolKey calldata key, bool swapForY, int128 amountSpecified, bytes calldata data)
external
override
Expand All @@ -56,10 +85,10 @@ contract BinReturnsDeltaHookOverwriteSwap is BaseBinTestHook {
_getInputOutputAndAmount(key, swapForY, amountSpecified);

// 1. Take input currency and amount
inputCurrency.take(vault, address(this), amount, false);
inputCurrency.take(vault, address(this), amount, true);

// 2. Give output currency and amount achieving a 1:1 swap
outputCurrency.settle(vault, address(this), amount, false);
outputCurrency.settle(vault, address(this), amount, true);

BeforeSwapDelta hookDelta = toBeforeSwapDelta(-amountSpecified, amountSpecified);
return (this.beforeSwap.selector, hookDelta, 0);
Expand Down

0 comments on commit 93c949f

Please sign in to comment.