This security review step provides confidence about how different types of actors can access the smart contract.
### Define a trust model
The first step is to write a written summary of what access rights different users are supposed to have. Below is a simplified trust model that could apply for a small AMM design.
- Pool governance can:
- Control swap fees and liquidity incentives
- Anyone can:
- Add liquidity and become a liquidity provider
- Trade against the pool
- Liquidity providers can
- Add and burn liquidity
- Claim swap fees
- Claim liquidity rewards.
It's important to specify the rights in user terms rather than function terms because the specific functions chosen in the smart contract may be incorrect.
### Generate a function modifier overview
The next step is to generate a technical overview of access control rights as they are defined in code.
One way to do that is to use the `describe` report in [Surya](notion://www.notion.so/codex/surya). This report will automatically feature any modifiers (e.g., `onlyOwner`) and should speed up the process. Beware that most access control rights are not captured in modifiers and can only be found in the code itself.
Example function overview (generated by Surya)
[Slither](/codex/slither) is also able to show which state variables are modified in each function and highlight any decision logic that depends on msg.sender.
### Go function-by-function to verify access control
Go into each function and verify that access control is in agreement in the trust model. If there is a discrepancy, review it with the authors.
### Review access control test coverage
Access control is so significant that it should have full coverage in tests. Review tests to make sure that each function is tested both with users that should be able to call it and those that shouldn't.
### Think through edge cases
Think about the broader implications of access control:
- Can access control be transferred to another user? What if that user becomes hostile?
- Could access control be transferred to the `0x0` address? What would be the implications if that happened?
- Is access control built using well understood primitives (e.g., OpenZeppelin `Ownable` and `AccessControl`) or custom-built?
- Is access control implemented consistently?
- Are access control changes marked with events?
### Fuzzing
Consider using [Fuzzing](/codex/fuzzing) to check if longer sequences of transactions could trigger unauthorized access.