Furthermore, I think splitting the contract in an Interface with events defined and the contract with the actual implementation will increase readability (similar to how the token bridge is structured).
Also, IMO we should split the contract into 2 layers:
AvalancheICTTRouter where users have to specify the fees when bridging
BipsFeeAvalancheICTTRouter where the fees are set at the router level
contract BipsFeeAvalancheICTTRouter is AvalancheICTTRouter
As suggested by Martin from Ava Labs:
Also, IMO we should split the contract into 2 layers:
AvalancheICTTRouter
where users have to specify the fees when bridgingBipsFeeAvalancheICTTRouter
where the fees are set at the router level