Handle a request
The handleRequest
function is used to simulate a law's execution without actually performing state changes. This is crucial for validating actions before they are executed.
Simulation Process
1. Function Signature
function handleRequest(
address caller,
address powers,
uint16 lawId,
bytes memory lawCalldata,
uint256 nonce
) public view virtual returns (
uint256 actionId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes memory stateChange
)
2. Simulation Steps
Action ID Generation
actionId = LawUtilities.hashActionId(lawId, lawCalldata, nonce);
Parameter Processing
Decode and validate input parameters
Check parameter constraints
Verify parameter relationships
Target Preparation
Determine target contracts
Prepare call data
Calculate required values
State Change Simulation
Simulate state changes
Validate state transitions
Prepare state change data
Implementation Requirements
1. View Function
Must be a
view
functionCannot modify state
Must return all necessary data
2. Return Values
actionId
: Unique identifier for the actiontargets
: Array of target contract addressesvalues
: Array of ETH values to sendcalldatas
: Array of encoded function callsstateChange
: Encoded state changes
3. Validation
Validate all input parameters
Check execution conditions
Verify state consistency
Ensure proper data formatting
Best Practices
Simulation Accuracy
Accurately simulate all state changes
Consider all edge cases
Validate all conditions
Check all constraints
Gas Optimization
Minimize memory usage
Use efficient data structures
Cache frequently accessed values
Optimize array operations
Error Handling
Validate all inputs
Check all conditions
Provide clear error messages
Handle edge cases
Security
Validate all parameters
Check for potential exploits
Verify data integrity
Protect against manipulation
Example Implementation
function handleRequest(
address caller,
address powers,
uint16 lawId,
bytes memory lawCalldata,
uint256 nonce
) public view virtual override returns (
uint256 actionId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes memory stateChange
) {
// Generate action ID
actionId = LawUtilities.hashActionId(lawId, lawCalldata, nonce);
// Decode parameters
(address target, uint256 value, bytes memory data) = abi.decode(
lawCalldata,
(address, uint256, bytes)
);
// Validate parameters
require(target != address(0), "Invalid target");
require(value <= maxValue, "Value too high");
// Prepare targets
targets = new address[](1);
targets[0] = target;
// Prepare values
values = new uint256[](1);
values[0] = value;
// Prepare calldatas
calldatas = new bytes[](1);
calldatas[0] = data;
// Simulate state changes
stateChange = abi.encode(
simulateStateChange(target, value, data)
);
return (actionId, targets, values, calldatas, stateChange);
}
Common Pitfalls
State Modification
Attempting to modify state in a view function
Using non-view functions in simulation
Modifying storage variables
Gas Estimation
Not considering gas costs
Creating unnecessarily large arrays
Using inefficient data structures
Validation
Missing parameter validation
Incomplete condition checks
Insufficient error handling
Data Formatting
Incorrect data encoding
Mismatched array lengths
Invalid parameter types
Last updated