TransactionManager - Receiver-side check also on sending side Fix
The functions `prepare`, `cancel`, and `fulfill` in the `TransactionManager` all have a “common part” that is executed on both the sending and the receiving chain and side-specific parts that are only executed either on the sending or on the receiving side.\\nThe following lines occur in fulfill's common part, but this should only be checked on the receiving chain. In fact, on the sending chain, we might even compare amounts of different assets.\\n```\\n// Sanity check: fee <= amount. Allow `=` in case of only wanting to execute\\n// 0-value crosschain tx, so only providing the fee amount\\nrequire(relayerFee <= txData.amount, "#F:023");\\n```\\n\\nThis could prevent a legitimate `fulfill` on the sending chain, causing a loss of funds for the router.
Resolution\\nThe Connext team claims to have fixed this in commit `4adbfd52703441ee5de655130fc2e0252eae4661`. We have not reviewed this commit or, generally, the codebase at this point.\\nMove these lines to the receiving-side part.\\nRemark\\nThe `callData` supplied to `fulfill` is not used at all on the sending chain, but the check whether its hash matches `txData.callDataHash` happens in the common part.\\n```\\n// Check provided callData matches stored hash\\nrequire(keccak256(callData) == txData.callDataHash, "#F:024");\\n```\\n\\nIn principle, this check could also be moved to the receiving-chain part, allowing the router to save some gas by calling sending-side `fulfill` with empty `callData` and skip the check. Note, however, that the `TransactionFulfilled` event will then also emit the “wrong” `callData` on the sending chain, so the off-chain code has to be able to deal with that if you want to employ this optimization.
```\\n// Sanity check: fee <= amount. Allow `=` in case of only wanting to execute\\n// 0-value crosschain tx, so only providing the fee amount\\nrequire(relayerFee <= txData.amount, "#F:023");\\n```\\n