@@ -13,6 +13,14 @@ import "../../utils/LibBytes.sol";
1313abstract contract ModuleAuthDynamic is ModuleAuthUpgradable {
1414 using LibBytes for bytes ;
1515
16+ /// @dev Struct to hold signature validation state to avoid stack too deep errors
17+ struct SignatureValidationState {
18+ uint256 rindex;
19+ bytes32 imageHash;
20+ uint256 totalWeight;
21+ bool immutableSignerContractFound;
22+ }
23+
1624 bytes32 public immutable INIT_CODE_HASH;
1725 address public immutable FACTORY;
1826 address public immutable IMMUTABLE_SIGNER_CONTRACT;
@@ -92,69 +100,67 @@ constructor(address _factory, address _startupWalletImpl, address _immutableSign
92100 uint256 rindex // read index
93101 ) = _signature.readFirstUint16 ();
94102
95- // Start image hash generation
96- bytes32 imageHash = bytes32 (uint256 (threshold));
97-
98- // Acumulated weight of signatures
99- uint256 totalWeight;
100-
101- // Track if immutable signer contract is one of the signers
102- bool immutableSignerContractFound = false ;
103+ SignatureValidationState memory state = SignatureValidationState ({
104+ rindex: rindex,
105+ imageHash: bytes32 (uint256 (threshold)),
106+ totalWeight: 0 ,
107+ immutableSignerContractFound: false
108+ });
103109
104110 // Iterate until the image is completed
105- while (rindex < _signature.length ) {
111+ while (state. rindex < _signature.length ) {
106112 // Read next item type and addrWeight
107113 uint256 flag; uint256 addrWeight; address addr;
108- (flag, addrWeight, rindex) = _signature.readUint8Uint8 (rindex);
114+ (flag, addrWeight, state. rindex) = _signature.readUint8Uint8 (state. rindex);
109115
110116 if (flag == FLAG_ADDRESS) {
111117 // Read plain address
112- (addr, rindex) = _signature.readAddress (rindex);
118+ (addr, state. rindex) = _signature.readAddress (state. rindex);
113119 } else if (flag == FLAG_SIGNATURE) {
114120 // Read single signature and recover signer
115121 bytes memory signature;
116- (signature, rindex) = _signature.readBytes66 (rindex);
122+ (signature, state. rindex) = _signature.readBytes66 (state. rindex);
117123 addr = recoverSigner (_hash, signature);
118124
119125 // Acumulate total weight of the signature
120- totalWeight += addrWeight;
126+ state. totalWeight += addrWeight;
121127 } else if (flag == FLAG_DYNAMIC_SIGNATURE) {
122128 // Read signer
123- (addr, rindex) = _signature.readAddress (rindex);
129+ (addr, state. rindex) = _signature.readAddress (state. rindex);
124130
125131 // Read signature size
126132 uint256 size;
127- (size, rindex) = _signature.readUint16 (rindex);
133+ (size, state. rindex) = _signature.readUint16 (state. rindex);
128134
129135 // Read dynamic size signature
130136 bytes memory signature;
131- (signature, rindex) = _signature.readBytes (rindex, size);
137+ (signature, state. rindex) = _signature.readBytes (state. rindex, size);
132138 require (isValidSignature (_hash, addr, signature), "ModuleAuthDynamic#_signatureValidation: INVALID_SIGNATURE " );
133139
134140 // Acumulate total weight of the signature
135- totalWeight += addrWeight;
141+ state. totalWeight += addrWeight;
136142 } else {
137143 revert ("ModuleAuthDynamic#_signatureValidation INVALID_FLAG " );
138144 }
139145
140146 // Check if this signer is the immutable signer contract
141147 if (addr == IMMUTABLE_SIGNER_CONTRACT) {
142- immutableSignerContractFound = true ;
148+ state. immutableSignerContractFound = true ;
143149 }
144150
145151 // Write weight and address to image
146- imageHash = keccak256 (abi.encode (imageHash, addrWeight, addr));
152+ state. imageHash = keccak256 (abi.encode (state. imageHash, addrWeight, addr));
147153 }
148154
149155 // Check if this is the first transaction (nonce was 0 before increment) and immutable signer contract is one of the signers
150156 // Note: _validateNonce increments the nonce before _signatureValidation is called, so we check for 1, not 0
151157 uint256 currentNonce = uint256 (ModuleStorage.readBytes32Map (NonceKey.NONCE_KEY, bytes32 (uint256 (0 ))));
152- if (currentNonce == 1 && immutableSignerContractFound) {
153- return (true , true , imageHash);
158+ if (currentNonce == 1 && state. immutableSignerContractFound) {
159+ return (true , true , state. imageHash);
154160 }
155161
156- (bool verified , bool needsUpdate ) = _isValidImage (imageHash);
157- return ((totalWeight >= threshold && verified), needsUpdate, imageHash);
162+ (bool verified , bool needsUpdate ) = _isValidImage (state. imageHash);
163+ return ((state. totalWeight >= threshold && verified), needsUpdate, state. imageHash);
158164 }
159165
160166 /**
0 commit comments