feat: USV3 verification

This commit is contained in:
TAMARA LIPOWSKI
2025-01-28 19:34:58 -05:00
parent f9ded54a0e
commit 7822c4f913
4 changed files with 50 additions and 3 deletions

3
.gitmodules vendored
View File

@@ -7,3 +7,6 @@
[submodule "foundry/lib/v2-core"] [submodule "foundry/lib/v2-core"]
path = foundry/lib/v2-core path = foundry/lib/v2-core
url = https://github.com/uniswap/v2-core url = https://github.com/uniswap/v2-core
[submodule "foundry/lib/v3-periphery"]
path = foundry/lib/v3-periphery
url = https://github.com/Uniswap/v3-periphery

View File

@@ -59,10 +59,13 @@ contract TychoRouter is
); );
event FeeSet(uint256 indexed oldFee, uint256 indexed newFee); event FeeSet(uint256 indexed oldFee, uint256 indexed newFee);
constructor(address _permit2, address weth) { address private immutable _usv3Factory;
constructor(address _permit2, address weth, address usv3Factory) {
permit2 = IAllowanceTransfer(_permit2); permit2 = IAllowanceTransfer(_permit2);
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_weth = IWETH(weth); _weth = IWETH(weth);
_usv3Factory = usv3Factory;
} }
/** /**
@@ -340,4 +343,41 @@ contract TychoRouter is
* @dev Allows this contract to receive native token * @dev Allows this contract to receive native token
*/ */
receive() external payable {} receive() external payable {}
/**
* @dev Called by UniswapV3 pool when swapping on it.
* See in IUniswapV3SwapCallback for documentation.
*/
function uniswapV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes calldata msgData
) external {
(uint256 amountOwed, address tokenOwed) =
_verifyUSV3Callback(amount0Delta, amount1Delta, msgData);
IERC20(tokenOwed).safeTransfer(msg.sender, amountOwed);
}
function _verifyUSV3Callback(
int256 amount0Delta,
int256 amount1Delta,
bytes calldata data
)
internal
pure
returns (uint256 amountOwed, address tokenOwed)
{
address tokenIn = address(bytes20(data[0:20]));
address tokenOut = address(bytes20(data[20:40]));
uint24 fee = uint24(bytes3(data[40:43]));
CallbackValidationV2.verifyCallback(
_usv3Factory, tokenIn, tokenOut, fee
);
amountOwed =
amount0Delta > 0 ? uint256(amount0Delta) : uint256(amount1Delta);
return (amountOwed, tokenOwed);
}
} }

View File

@@ -8,7 +8,9 @@ import "@src/TychoRouter.sol";
import {WETH} from "../lib/permit2/lib/solmate/src/tokens/WETH.sol"; import {WETH} from "../lib/permit2/lib/solmate/src/tokens/WETH.sol";
contract TychoRouterExposed is TychoRouter { contract TychoRouterExposed is TychoRouter {
constructor(address _permit2, address weth) TychoRouter(_permit2, weth) {} constructor(address _permit2, address weth, address usv3Factory)
TychoRouter(_permit2, weth, usv3Factory)
{}
function wrapETH(uint256 amount) external payable { function wrapETH(uint256 amount) external payable {
return _wrapETH(amount); return _wrapETH(amount);
@@ -39,7 +41,8 @@ contract TychoRouterTestSetup is Test, Constants {
vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock); vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock);
vm.startPrank(ADMIN); vm.startPrank(ADMIN);
tychoRouter = new TychoRouterExposed(permit2Address, WETH_ADDR); tychoRouter =
new TychoRouterExposed(permit2Address, WETH_ADDR, address(0));
tychoRouterAddr = address(tychoRouter); tychoRouterAddr = address(tychoRouter);
tychoRouter.grantRole(keccak256("FUND_RESCUER_ROLE"), FUND_RESCUER); tychoRouter.grantRole(keccak256("FUND_RESCUER_ROLE"), FUND_RESCUER);
tychoRouter.grantRole(keccak256("FEE_SETTER_ROLE"), FEE_SETTER); tychoRouter.grantRole(keccak256("FEE_SETTER_ROLE"), FEE_SETTER);