Calls Made to Non-Existent/Removed Routes or Controllers Will Not Result in Failure
This issue was found in commit hash `a8d0ad1c280a699d88dc280d9648eacaf215fb41`.\\nIn the Ethereum Virtual Machine (EVM), `delegatecall` will succeed for calls to externally owned accounts and more specifically to the zero address, which presents a potential security risk. We have identified multiple instances of `delegatecall` being used to invoke smart contract functions.\\nThis, combined with the fact that routes can be removed from the system by the owner of the `SocketGateway` contract using the `disableRoute` function, makes it possible for the user's funds to be lost in case of an `executeRoute` transaction (for instance) that's waiting in the mempool is eventually being front-ran by a call to `disableRoute`.\\n```\\n(bool success, bytes memory result) = addressAt(routeId).delegatecall(\\n```\\n\\n```\\n.delegatecall(swapData);\\n```\\n\\n```\\n.delegatecall(swapData);\\n```\\n\\n```\\n.delegatecall(swapData);\\n```\\n\\n```\\n.delegatecall(data);\\n```\\n\\nEven after the upgrade to commit hash `d0841a3e96b54a9d837d2dba471aa0946c3c8e7b`, the following bug is still present:\\nTo optimize gas usage, the `addressAt` function in `socketGateway` uses a binary search in a hard-coded table to resolve a `routeID` (routeID <= 512) to a contract address. This is made possible thanks to the factory using the `CREATE2` pattern. This allows to pre-compute future addresses of contracts before they are deployed. In case the `routeID` is strictly greater than 512, `addressAt` falls back to fetching the address from a state mapping (routes).\\nThe new commit hash adds a check to make sure that the call to the `addressAt` function reverts in case a `routeID` is not present in the `routes` mapping. This prevents delegate-calling to non-existent addresses in various places of the code. However, this does not solve the issue for the hard-coded route addresses (i.e., `routeID` <= 512). In that case, the `addressAt` function still returns a valid route contract address, despite the contract not being deployed yet. This will result in a successful `delegatecall` later in the code and might lead to various side-effects.\\n```\\nfunction addressAt(uint32 routeId) public view returns (address) {\\n    if (routeId < 513) {\\n        if (routeId < 257) {\\n            if (routeId < 129) {\\n                if (routeId < 65) {\\n                    if (routeId < 33) {\\n                        if (routeId < 17) {\\n                            if (routeId < 9) {\\n                                if (routeId < 5) {\\n                                    if (routeId < 3) {\\n                                        if (routeId == 1) {\\n                                            return\\n                                                0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\\n                                        } else {\\n                                            return\\n                                                0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\\n                                        }\\n                                    } else {\\n```\\n\\n```\\nif (routes[routeId] == address(0)) revert ZeroAddressNotAllowed();\\nreturn routes[routeId];\\n```\\n
Consider adding a check to validate that the callee of a `delegatecall` is indeed a contract, you may refer to the Address library by OZ.
```\\n(bool success, bytes memory result) = addressAt(routeId).delegatecall(\\n```\\n