Learning from uniswap source code
- to avoid gas cost from reverting transactions, need to simulate computations to get expected output before running critical logics
- to support easy onchain / offchain data sync, build pure helper functions
- to write safe code, set the invariants & responsibility for each module / function clearly
- generalizable functions, like swap()