Skip to content

feat: Add delegate call guard functionality to SafeTxPool #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 3, 2025

Conversation

hadv
Copy link
Owner

@hadv hadv commented Jul 3, 2025

Summary

This PR implements a comprehensive delegate call guard mechanism for the SafeTxPool contract, allowing Safe wallets to control when and where delegate calls (operation = 1) can be executed.

Features Added

🔒 Delegate Call Control System

  • Disabled by default: All new Safes have delegate calls disabled for maximum security
  • Per-Safe configuration: Each Safe can independently enable/disable delegate calls
  • Target whitelisting: Optional granular control over which contracts can be delegate-called

🛠 Management Functions

  • setDelegateCallEnabled(address safe, bool enabled) - Enable/disable delegate calls
  • addDelegateCallTarget(address safe, address target) - Add allowed delegate call target
  • removeDelegateCallTarget(address safe, address target) - Remove allowed target
  • isDelegateCallEnabled(address safe) - Check if delegate calls are enabled
  • isDelegateCallTargetAllowed(address safe, address target) - Check if target is allowed

🔐 Security Model

Three Progressive Security Levels:

  1. Level 1 - Disabled (Default): All delegate calls blocked - Maximum security
  2. Level 2 - Enabled, No Restrictions: Delegate calls to any address book entry - Moderate security
  3. Level 3 - Enabled with Target Restrictions: Only whitelisted targets allowed - High security with controlled flexibility

Always Allowed Operations:

  • Safe calling itself (required for owner management, threshold changes)
  • Safe calling the guard contract (required for settings management)

📊 Events & Error Handling

  • DelegateCallToggled(address indexed safe, bool enabled)
  • DelegateCallTargetAdded(address indexed safe, address indexed target)
  • DelegateCallTargetRemoved(address indexed safe, address indexed target)
  • Custom errors: DelegateCallDisabled(), DelegateCallTargetNotAllowed()

Files Changed

Core Implementation

  • src/SafeTxPool.sol: Enhanced with delegate call guard functionality
    • Added state variables for delegate call control
    • Modified checkTransaction to enforce delegate call restrictions
    • Added management functions for delegate call settings
    • Added events and custom errors

Testing

  • test/SafeTxPoolDelegateCallGuard.t.sol: Comprehensive test suite (9 tests)
    • Tests default disabled state
    • Tests enabling/disabling functionality
    • Tests target whitelisting
    • Tests integration with existing address book functionality
    • Tests permission controls and error conditions

Documentation & Examples

  • DELEGATE_CALL_GUARD.md: Complete documentation with usage examples
  • script/DelegateCallGuardExample.s.sol: Working example script demonstrating all features

Testing Results

All tests passing: 61 total tests (9 new + 52 existing)
No breaking changes: All existing functionality preserved
Comprehensive coverage: Edge cases, error conditions, and integration scenarios tested

Ran 7 test suites: 61 tests passed, 0 failed, 0 skipped

Usage Example

// 1. Add target to address book (existing requirement)
pool.addAddressBookEntry(address(safe), targetContract, "My Target Contract");

// 2. Enable delegate calls
pool.setDelegateCallEnabled(address(safe), true);

// 3. (Optional) Add target restrictions for enhanced security
pool.addDelegateCallTarget(address(safe), targetContract);

// 4. Delegate calls to targetContract are now allowed
// Normal Safe transaction execution will pass the guard checks

Migration & Backward Compatibility

  • Zero breaking changes: Existing Safe wallets continue to work unchanged
  • Secure by default: Existing Safes have delegate calls disabled until explicitly enabled
  • Gradual adoption: Safe owners can enable delegate calls when needed

Security Considerations

  • Defense in depth: Works alongside existing address book restrictions
  • Principle of least privilege: Disabled by default, explicit enablement required
  • Granular control: Optional target whitelisting for additional security
  • Audit-friendly: Clear events and error messages for monitoring

Related Issues

Implements delegate call guard functionality as requested to provide on/off control for delegate calls (operation = 1) in SafeTxPool.


Ready for review 🚀


Pull Request opened by Augment Code with guidance from the PR author

hadv added 2 commits July 3, 2025 04:15
- Add comprehensive delegate call control system with per-Safe configuration
- Implement three security levels: disabled (default), enabled, and restricted
- Add management functions for enabling/disabling and target whitelisting
- Enhance checkTransaction to enforce delegate call restrictions
- Add events and custom errors for delegate call operations
- Maintain backward compatibility with existing functionality
- Add comprehensive test suite with 9 new tests
- Add documentation and example script
- All 61 tests passing with zero breaking changes

Implements on/off control for delegate calls (operation = 1) as requested.
- Consolidate long function calls onto single lines
- Remove trailing whitespace
- Apply consistent Solidity formatting standards
@hadv hadv merged commit 62c751a into main Jul 3, 2025
3 checks passed
@hadv hadv deleted the feat/delegate-call-guard branch July 3, 2025 04:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant