Design Patterns Used & Why:
- Fail early and fail loud: Require is used throughout to indicate parameters of each function, including as modifiers and function-by-function
- Restricting Access: Roles are implemented throughout the contract as described in the readme
- Pull over Push Payments: The withdrawal pattern is used to avoid reentrancy and extended transfer loops
- Circuit Breaker: Pausable is imported from OpenZeppelin to allow deposits, withdrawals, and project approval to be paused in the event of an emergency
- State Machine: The entire contract is a state machine architecture to reflect typical project finance workflow