crytic / crytic/slither

Enhancement: Detect Complex Struct Getters with Omitted Members

Open
#2,779 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Python
Stars
6.4k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

## Summary
Add a detector that identifies public state variables containing complex structs where automatic getters omit certain members, potentially causing confusion and incorrect assumptions about data accessibility.

## Motivation

Solidity automatically generates getter functions for public state variables. However, these getters have limitations when dealing with complex data structures:

1. **Arrays and mappings within structs are omitted** from the generated getter
2. **Nested structs with arrays/mappings** are partially omitted
3. **Developers may assume** all struct members are accessible via the getter

This behavior is not immediately obvious and can lead to:
- Incorrect assumptions about data availability
- Inefficient workarounds when data appears inaccessible
- Security issues if access control depends on getter visibility
- Integration problems with external contracts or front-ends

## Problem Description

When a struct contains arrays or mappings, Solidity's automatic getter will skip these members:

```solidity
struct UserData {
string name; // ✓ Included in getter
uint256 balance; // ✓ Included in getter
uint256[] tokenIds; // ✗ Omitted from getter
mapping(address => uint256) allowances; // ✗ Omitted from getter
}

contract Example {
UserData public userData; // Getter won't return tokenIds or allowances
}
```

## Example Vulnerable Patterns

```solidity
contract ProblematicPatterns {
// Pattern 1: Direct struct with arrays/mappings
struct Config {
address owner;
uint256[] limits; // Won't be in getter
mapping(address => bool) whitelist; // Won't be in getter
}
Config public config; // Getter omits limits and whitelist

// Pattern 2: Nested structs
struct Inner {
uint256[] values; // Won't be accessible
}
struct Outer {
Inner data; // Partially accessible
string name;
}
Outer public settings; // Getter omits Inner.values

// Pattern 3: Array of structs with complex members
struct Token {
string symbol;
address[] holders; // Omitted when accessing array elements
}
Token[] public tokens; // Individual token getters omit holders
}
```

## Recommended Solutions

The detector should suggest alternatives:

```solidity
contract ImprovedPatterns {
struct Config {
address owner;
uint256[] limits;
mapping(address => bool) whitelist;
}

// Solution 1: Make variable private/internal and create custom getter
Config private config;

function getConfig() external view returns (
address owner,
uint256[] memory limits
) {
return (config.owner, config.limits);
}

// Solution 2: Separate simple and complex data
struct SimpleConfig {
address owner;
uint256 limitCount;
}
SimpleConfig public simpleConfig;
uint256[] public limits;
}
```

## Expected Output

```
Complex struct getter detected in ContractName
State variable: config (line 45)
Type: Config
Omitted members:
- limits: uint256[] (line 12)
- whitelist: mapping(address => bool) (line 13)

Impact: Automatic getter does not return these members
Recommendation: Create a custom getter function or separate complex members
```

## Benefits

1. **Prevent integration issues** - External contracts/UIs won't be surprised by missing data
2. **Improve code clarity** - Developers understand data accessibility
3. **Reduce gas costs** - Avoid unnecessary workarounds for accessing "hidden" data
4. **Educational value** - Teaches Solidity's getter limitations
5. **Better API design** - Encourages thoughtful public interface design

## Priority

**Medium-High** - While not directly a security vulnerability, this issue frequently causes integration problems, increases development time, and can indirectly lead to security issues when developers implement workarounds. It's particularly important for contracts intended to be integrated with other systems.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.