Router.sol is vulnerable to address collission
The pool address check in the the callback function isn't strict enough and can suffer issues with collision. Due to the truncated nature of the create2 opcode the collision resistance is already impaired to 2^160 as that is total number of possible hashes after truncation. Obviously if you are searching for a single hash, this is (basically) impossible. The issue here is that one does not need to search for a single address as the router never verifies that the pool actually exists. This is the crux of the problem, but first let's do a little math as to why this is a problem.\\n$$ 1 - e ^ {-k(k-1) \\over 2N } $$\\nWhere k is the number of hash values and N is the number of possible hashes\\nFor very large numbers we can further approximate the exponent to:\\n$$ -k^2 \\over 2N $$\\nThis exponent is now trivial to solve for an approximate attack value which is:\\n$$ k = \\sqrt{2N} $$\\nIn our scenario N is 2^160 (our truncated keccak256) which means that our approximate attack value is 2^80 since we need to generate two sets of hashes. The first set is to generate 2^80 public addresses and the second is to generate pool address from variations in the pool specifics(token0, token1, fee). Here we reach a final attack value of 2^81 hashes. Using the provided calculator we see that 2^81 hashes has an approximate 86.4% chance of a collision. Increase that number to 2^82 and the odds of collision becomes 99.96%. In this case, a collision between addresses means breaking this check and draining the allowances of all users to a specific token. This is because the EOA address will collide with the supposed pool address allowing it to bypass the msg.sender check. Now we considered the specific of the contract.\\nRouter.sol#L47-L51\\n```\\nrequire(\\n  msg.sender == address(_getPool(tokenIn, tokenOut, fee)),\\n  'Router: invalid callback sender'\\n);\\n```\\n\\nThe above snippet from the swapCallback function is used to verify that msg.sender is the address of the pool.\\nRouter.sol#L224-L231\\n```\\nfunction _getPool(\\n    address tokenA,\\n    address tokenB,\\n    uint24 fee\\n) private view returns (IPool) {\\n    return IPool(PoolAddress.computeAddress(factory, tokenA, tokenB, fee, poolInitHash));\\n}\\n```\\n\\nWe see that these lines never check with the factory that the pool exists or any of the inputs are valid in any way. token0 can be constant and we can achieve the variation in the hash by changing token1. The attacker could use token0 = WETH and vary token1. This would allow them to steal all allowances of WETH. Since allowances are forever until revoked, this could put hundreds of millions of dollars at risk.\\nAlthough this would require a large amount of compute it is already possible to break with current computing. Given the enormity of the value potentially at stake it would be a lucrative attack to anyone who could fund it. In less than a decade this would likely be a fairly easily attained amount of compute, nearly guaranteeing this attack.
Verify with the factory that msg.sender is a valid pool
Address collision can cause all allowances to be drained
```\\nrequire(\\n  msg.sender == address(_getPool(tokenIn, tokenOut, fee)),\\n  'Router: invalid callback sender'\\n);\\n```\\n