pragma solidity ^0.8.26;
import "forge-std/console.sol";
import {Test} from "forge-std/Test.sol";
import {ReFiSwapRebateHook} from "../src/RebateFiHook.sol";
import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol";
import {PoolSwapTest} from "v4-core/test/PoolSwapTest.sol";
import {MockERC20} from "solmate/src/test/utils/mocks/MockERC20.sol";
import {PoolManager} from "v4-core/PoolManager.sol";
import {IPoolManager} from "v4-core/interfaces/IPoolManager.sol";
import {SwapParams, ModifyLiquidityParams} from "v4-core/types/PoolOperation.sol";
import {CustomRevert} from "v4-core/libraries/CustomRevert.sol";
import {Currency, CurrencyLibrary} from "v4-core/types/Currency.sol";
import {ERC1155TokenReceiver} from "solmate/src/tokens/ERC1155.sol";
import {PoolKey} from "v4-core/types/PoolKey.sol";
import {PoolId} from "v4-core/types/PoolId.sol";
import {Hooks} from "v4-core/libraries/Hooks.sol";
import {IHooks} from "v4-core/interfaces/IHooks.sol";
import {TickMath} from "v4-core/libraries/TickMath.sol";
import {SqrtPriceMath} from "v4-core/libraries/SqrtPriceMath.sol";
import {LiquidityAmounts} from "@uniswap/v4-core/test/utils/LiquidityAmounts.sol";
import {HookMiner} from "v4-periphery/src/utils/HookMiner.sol";
import {LPFeeLibrary} from "v4-core/libraries/LPFeeLibrary.sol";
contract TestReFiSwapRebateHook_02 is Test, Deployers, ERC1155TokenReceiver {
MockERC20 token;
MockERC20 reFiToken;
MockERC20 someBiggerToken;
ReFiSwapRebateHook public rebateHook;
Currency ethCurrency = Currency.wrap(address(0));
Currency tokenCurrency;
Currency reFiCurrency;
Currency someBiggerCurrency;
address user1 = address(0x1);
address user2 = address(0x2);
uint160 constant SQRT_PRICE_1_1_s = 79228162514264337593543950336;
function setUp() public {
deployFreshManagerAndRouters();
token = new MockERC20("TOKEN", "TKN", 18);
tokenCurrency = Currency.wrap(address(token));
reFiToken = new MockERC20("ReFi Token", "ReFi", 18);
reFiCurrency = Currency.wrap(address(reFiToken));
someBiggerToken = new MockERC20("BiggerToken", "BTKN", 18);
someBiggerCurrency = Currency.wrap(address(someBiggerToken));
token.mint(address(this), 1000 ether);
token.mint(user1, 1000 ether);
token.mint(user2, 1000 ether);
reFiToken.mint(address(this), 1000 ether);
reFiToken.mint(user1, 1000 ether);
reFiToken.mint(user2, 1000 ether);
someBiggerToken.mint(address(this), 1000 ether);
someBiggerToken.mint(user1, 1000 ether);
someBiggerToken.mint(user2, 1000 ether);
bytes memory creationCode = type(ReFiSwapRebateHook).creationCode;
bytes memory constructorArgs = abi.encode(manager, address(reFiToken));
uint160 flags = uint160(
Hooks.BEFORE_INITIALIZE_FLAG |
Hooks.AFTER_INITIALIZE_FLAG |
Hooks.BEFORE_SWAP_FLAG
);
(address hookAddress, bytes32 salt) = HookMiner.find(
address(this),
flags,
creationCode,
constructorArgs
);
rebateHook = new ReFiSwapRebateHook{salt: salt}(manager, address(reFiToken));
require(address(rebateHook) == hookAddress, "Hook address mismatch");
token.approve(address(swapRouter), type(uint256).max);
token.approve(address(modifyLiquidityRouter), type(uint256).max);
reFiToken.approve(address(rebateHook), type(uint256).max);
reFiToken.approve(address(swapRouter), type(uint256).max);
reFiToken.approve(address(modifyLiquidityRouter), type(uint256).max);
someBiggerToken.approve(address(rebateHook), type(uint256).max);
someBiggerToken.approve(address(swapRouter), type(uint256).max);
someBiggerToken.approve(address(modifyLiquidityRouter), type(uint256).max);
}
INITIALIZATION TESTS
══════════════════════════════════════════════════════════════════ */
function test_ReFiSwapRebateHook_02_InitPoolFailed() public {
PoolKey memory key;
Currency currency0_ = reFiCurrency;
Currency currency1_ = someBiggerCurrency;
IHooks iHooks_ = IHooks(address(rebateHook));
uint24 fee_ = LPFeeLibrary.DYNAMIC_FEE_FLAG;
uint160 sqrtPriceX96_ = SQRT_PRICE_1_1_s;
PoolKey memory key_ = PoolKey(currency0_, currency1_, fee_, (fee_ == LPFeeLibrary.DYNAMIC_FEE_FLAG) ? int24(60) : int24(fee_ / 100 * 2), iHooks_);
bytes memory data = abi.encodeCall(IHooks.beforeInitialize, (address(this), key_, sqrtPriceX96_));
bytes memory reason = abi.encodeWithSelector(ReFiSwapRebateHook.ReFiNotInPool.selector);
bytes memory details = abi.encodePacked(Hooks.HookCallFailed.selector);
vm.expectRevert(
abi.encodeWithSelector(
CustomRevert.WrappedError.selector,
address(rebateHook),
bytes4(data),
reason,
details
)
);
(key, ) = initPool(
currency0_,
currency1_,
iHooks_,
fee_,
sqrtPriceX96_
);
}
}
Ran 1 test for test/RebateFiHookTest_02.t.sol:TestReFiSwapRebateHook_02
[PASS] test_ReFiSwapRebateHook_02_InitPoolFailed() (gas: 31146)
Traces:
[31146] TestReFiSwapRebateHook_02::test_ReFiSwapRebateHook_02_InitPoolFailed()
├─ [0] VM::expectRevert(custom error 0xf28dceb3: 0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010490bfb8650000000000000000000000000c897a35742f0d25307c60b28bd526c0aa777080dc98354e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000047ac0d4d7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a9e35b2f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
│ └─ ← [Return]
├─ [10047] PoolManager::initialize(PoolKey({ currency0: 0x212224D2F2d262cd093eE13240ca4873fcCBbA3C, currency1: 0x2a07706473244BC757E10F2a9E86fB532828afe3, fee: 8388608 [8.388e6], tickSpacing: 60, hooks: 0x0C897A35742f0d25307c60b28bD526c0aA777080 }), 79228162514264337593543950336 [7.922e28])
│ ├─ [1598] ReFiSwapRebateHook::beforeInitialize(TestReFiSwapRebateHook_02: [0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496], PoolKey({ currency0: 0x212224D2F2d262cd093eE13240ca4873fcCBbA3C, currency1: 0x2a07706473244BC757E10F2a9E86fB532828afe3, fee: 8388608 [8.388e6], tickSpacing: 60, hooks: 0x0C897A35742f0d25307c60b28bD526c0aA777080 }), 79228162514264337593543950336 [7.922e28])
│ │ └─ ← [Revert] ReFiNotInPool()
│ └─ ← [Revert] WrappedError(0x0C897A35742f0d25307c60b28bD526c0aA777080, 0xdc98354e, 0x7ac0d4d7, 0xa9e35b2f)
└─ ← [Stop]
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 12.14ms (177.20µs CPU time)