- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
8.2 KiB
Decision Tree: OpenZeppelin vs Custom Implementation
Overview
This decision tree helps you choose between OpenZeppelin and custom implementations when creating new contracts.
Decision Tree
Start
|
├─ Do you need token operations?
| |
| ├─ Yes → Standard ERC20 tokens?
| | |
| | ├─ Yes → Use Minimal IERC20 Interface ✅
| | | (Reference: CCIPWETH9Bridge.sol)
| | |
| | └─ No → Non-standard tokens?
| | |
| | ├─ Yes → Use SafeERC20 (OpenZeppelin) ⚠️
| | |
| | └─ No → Use Minimal IERC20 Interface ✅
| |
| └─ No → Continue
|
├─ Do you need access control?
| |
| ├─ Yes → Simple admin pattern?
| | |
| | ├─ Yes → Use Custom Admin Pattern ✅
| | | (Reference: CCIPWETH9Bridge.sol)
| | |
| | └─ No → Complex access control?
| | |
| | ├─ Yes → Use OpenZeppelin Access Control ⚠️
| | |
| | └─ No → Use Custom Admin Pattern ✅
| |
| └─ No → Continue
|
├─ Do you need security features?
| |
| ├─ Yes → Battle-tested needed?
| | |
| | ├─ Yes → Use OpenZeppelin ⚠️
| | |
| | └─ No → Use Custom Implementation ✅
| |
| └─ No → Continue
|
├─ Gas optimization critical?
| |
| ├─ Yes → Use Custom Implementation ✅
| |
| └─ No → Continue
|
├─ Code size critical?
| |
| ├─ Yes → Use Custom Implementation ✅
| |
| └─ No → Continue
|
└─ Default: Use Custom Implementation ✅
Decision Matrix
Token Operations
| Scenario | Recommendation | Reason |
|---|---|---|
| Standard ERC20 tokens | ✅ Minimal IERC20 Interface | No external dependency, smaller code |
| Non-standard ERC20 tokens | ⚠️ SafeERC20 (OpenZeppelin) | Handles non-standard tokens |
| Unknown token types | ⚠️ SafeERC20 (OpenZeppelin) | Safety first |
| Known standard tokens | ✅ Minimal IERC20 Interface | Optimized for known tokens |
Access Control
| Scenario | Recommendation | Reason |
|---|---|---|
| Simple admin pattern | ✅ Custom Admin Pattern | No external dependency, simpler |
| Complex access control | ⚠️ OpenZeppelin Access Control | Battle-tested, complex features |
| Multi-role access | ⚠️ OpenZeppelin Access Control | Complex features needed |
| Single admin | ✅ Custom Admin Pattern | Simple, no dependency |
Security Features
| Scenario | Recommendation | Reason |
|---|---|---|
| Battle-tested needed | ⚠️ OpenZeppelin | Proven security |
| Simple security | ✅ Custom Implementation | No external dependency |
| Complex security | ⚠️ OpenZeppelin | Complex features needed |
| Standard patterns | ✅ Custom Implementation | Simple, maintainable |
Gas Optimization
| Scenario | Recommendation | Reason |
|---|---|---|
| Gas optimization critical | ✅ Custom Implementation | Lower gas costs |
| Gas not critical | Either | Choose based on other factors |
| High-frequency operations | ✅ Custom Implementation | Lower gas costs |
| Low-frequency operations | Either | Choose based on other factors |
Code Size
| Scenario | Recommendation | Reason |
|---|---|---|
| Code size critical | ✅ Custom Implementation | Smaller code size |
| Code size not critical | Either | Choose based on other factors |
| Contract size limits | ✅ Custom Implementation | Smaller code size |
| No size constraints | Either | Choose based on other factors |
Use Cases
Use Custom Implementation When:
-
✅ Standard ERC20 tokens only
- Use minimal IERC20 interface
- Reference: CCIPWETH9Bridge.sol
-
✅ Simple admin pattern
- Use custom admin pattern
- Reference: CCIPWETH9Bridge.sol
-
✅ Gas optimization critical
- Use custom implementation
- Lower gas costs
-
✅ Code size critical
- Use custom implementation
- Smaller code size
-
✅ No external dependencies desired
- Use custom implementation
- Better maintainability
Use OpenZeppelin When:
-
⚠️ Non-standard ERC20 tokens
- Use SafeERC20
- Handles non-standard tokens
-
⚠️ Complex access control
- Use OpenZeppelin Access Control
- Complex features needed
-
⚠️ Battle-tested security needed
- Use OpenZeppelin
- Proven security
-
⚠️ Time constraints
- Use OpenZeppelin
- Faster development
-
⚠️ Standard patterns needed
- Use OpenZeppelin
- Industry standard
Examples
Example 1: Token Bridge
Scenario: Cross-chain token bridge with standard ERC20 tokens
Decision: ✅ Custom Implementation
- Use minimal IERC20 interface
- Use custom admin pattern
- No external dependencies
Reference: contracts/ccip/CCIPWETH9Bridge.sol
Example 2: Multi-Sig Wallet
Scenario: Multi-signature wallet with complex access control
Decision: ⚠️ OpenZeppelin (or Gnosis Safe)
- Complex access control needed
- Battle-tested security required
- Consider Gnosis Safe for production
Reference: contracts/governance/MultiSig.sol
Example 3: Token Staking
Scenario: Token staking with standard ERC20 tokens
Decision: ✅ Custom Implementation
- Use minimal IERC20 interface
- Use custom admin pattern
- No external dependencies
Example 4: Voting Contract
Scenario: Simple voting contract with admin functions
Decision: ✅ Custom Implementation
- Use custom admin pattern
- No external dependencies
- Simple access control
Reference: contracts/governance/Voting.sol (currently uses Ownable, can be refactored)
Checklist
Before Choosing Custom Implementation
- Standard ERC20 tokens only?
- Simple access control sufficient?
- Gas optimization important?
- Code size important?
- No external dependencies desired?
- Time available for custom implementation?
Before Choosing OpenZeppelin
- Non-standard tokens needed?
- Complex access control needed?
- Battle-tested security required?
- Time constraints?
- Standard patterns needed?
- External dependency acceptable?
Recommendations
For New Contracts
-
Start with Custom Implementation
- Use minimal interfaces
- Use custom admin pattern
- No external dependencies
-
Use OpenZeppelin Only When Needed
- Non-standard tokens
- Complex access control
- Battle-tested security required
-
Follow Patterns from New WETH Contracts
- CCIPWETH9Bridge.sol
- CCIPWETH10Bridge.sol
- WETH10.sol
For Existing Contracts
-
Refactor When Possible
- Replace SafeERC20 with standard ERC20 calls
- Replace Ownable with custom admin pattern
- Reduce external dependencies
-
Keep OpenZeppelin When Needed
- Non-standard tokens
- Complex access control
- Battle-tested security required
References
Contract Examples
contracts/ccip/CCIPWETH9Bridge.sol- Custom implementation ✅contracts/ccip/CCIPWETH10Bridge.sol- Custom implementation ✅contracts/tokens/WETH10.sol- Custom implementation ✅contracts/ccip/CCIPSender.sol- Uses OpenZeppelin ⚠️contracts/governance/MultiSig.sol- Uses OpenZeppelin ⚠️
Documentation
Summary
Default Recommendation: ✅ Custom Implementation
- Use minimal interfaces
- Use custom admin pattern
- No external dependencies
- Better maintainability
- Lower gas costs
- Smaller code size
Use OpenZeppelin When: ⚠️
- Non-standard tokens needed
- Complex access control needed
- Battle-tested security required
- Time constraints
Questions?
For questions about choosing between OpenZeppelin and custom implementations, refer to: