Skip to content

Commit c835485

Browse files
committed
Optimise stack usage
1 parent ba4e8e8 commit c835485

1 file changed

Lines changed: 32 additions & 37 deletions

File tree

src/contracts/modules/commons/ModuleAuthDynamic.sol

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -66,74 +66,69 @@ constructor(address _factory, address _startupWalletImpl, address _immutableSign
6666
uint256 rindex // read index
6767
) = _signature.readFirstUint16();
6868

69-
SignatureValidationState memory state = SignatureValidationState({
70-
rindex: rindex,
71-
imageHash: bytes32(uint256(threshold)),
72-
totalWeight: 0,
73-
immutableSignerContractSigned: false
74-
});
69+
bytes32 imageHash = bytes32(uint256(threshold));
70+
uint256 totalWeight = 0;
71+
bool immutableSignerContractSigned = false;
7572

7673
// Iterate until the image is completed
77-
while (state.rindex < _signature.length) {
74+
while (rindex < _signature.length) {
7875
// Read next item type and addrWeight
7976
uint256 flag; uint256 addrWeight; address addr;
80-
(flag, addrWeight, state.rindex) = _signature.readUint8Uint8(state.rindex);
77+
(flag, addrWeight, rindex) = _signature.readUint8Uint8(rindex);
8178

8279
// Note: FLAG_ADDRESS is intentionally not supported in this module to prevent
8380
// attackers from including the immutable signer address without providing a valid signature.
8481
// Only FLAG_SIGNATURE and FLAG_DYNAMIC_SIGNATURE are allowed.
8582
if (flag == FLAG_SIGNATURE) {
8683
// Read single signature and recover signer
8784
bytes memory signature;
88-
(signature, state.rindex) = _signature.readBytes66(state.rindex);
85+
(signature, rindex) = _signature.readBytes66(rindex);
8986
addr = recoverSigner(_hash, signature);
90-
91-
// Accumulate total weight of the signature
92-
state.totalWeight += addrWeight;
93-
94-
// Check if this signer is the immutable signer contract (only after signature verification)
95-
if (addr == IMMUTABLE_SIGNER_CONTRACT) {
96-
state.immutableSignerContractSigned = true;
97-
}
9887
} else if (flag == FLAG_DYNAMIC_SIGNATURE) {
9988
// Read signer
100-
(addr, state.rindex) = _signature.readAddress(state.rindex);
101-
102-
// Read signature size
103-
uint256 size;
104-
(size, state.rindex) = _signature.readUint16(state.rindex);
89+
(addr, rindex) = _signature.readAddress(rindex);
10590

106-
// Read dynamic size signature
10791
bytes memory signature;
108-
(signature, state.rindex) = _signature.readBytes(state.rindex, size);
92+
(signature, rindex) = checkSig(_signature, rindex);
10993
require(isValidSignature(_hash, addr, signature), "ModuleAuthDynamic#_signatureValidation: INVALID_SIGNATURE");
110-
111-
// Accumulate total weight of the signature
112-
state.totalWeight += addrWeight;
113-
114-
// Check if this signer is the immutable signer contract (only after signature verification)
115-
if (addr == IMMUTABLE_SIGNER_CONTRACT) {
116-
state.immutableSignerContractSigned = true;
117-
}
11894
} else {
11995
revert("ModuleAuthDynamic#_signatureValidation INVALID_FLAG");
12096
}
12197

98+
// Check if this signer is the immutable signer contract (only after signature verification)
99+
if (addr == IMMUTABLE_SIGNER_CONTRACT) {
100+
immutableSignerContractSigned = true;
101+
}
102+
122103
// Write weight and address to image
123-
state.imageHash = keccak256(abi.encode(state.imageHash, addrWeight, addr));
104+
imageHash = keccak256(abi.encode(imageHash, addrWeight, addr));
105+
106+
// Accumulate total weight of the signature
107+
totalWeight += addrWeight;
124108
}
125109

126110
// Check if this is the first transaction (nonce was 0 before increment) and immutable signer contract
127111
// has provided a valid signature. The immutable signer must have actually signed (not just be listed
128112
// as an address) and the total weight must meet the threshold to prevent unauthorized bootstrap attacks.
129113
// Note: _validateNonce increments the nonce before _signatureValidation is called, so we check for 1, not 0
130114
uint256 currentNonce = uint256(ModuleStorage.readBytes32Map(NonceKey.NONCE_KEY, bytes32(uint256(0))));
131-
if (currentNonce == 1 && state.immutableSignerContractSigned && state.totalWeight >= threshold) {
132-
return (true, true, state.imageHash);
115+
if (currentNonce == 1 && immutableSignerContractSigned && totalWeight >= threshold) {
116+
return (true, true, imageHash);
133117
}
134118

135-
(bool verified, bool needsUpdate) = _isValidImage(state.imageHash);
136-
return ((state.totalWeight >= threshold && verified), needsUpdate, state.imageHash);
119+
(bool verified, bool needsUpdate) = _isValidImage(imageHash);
120+
return ((totalWeight >= threshold && verified), needsUpdate, imageHash);
121+
}
122+
123+
function checkSig(bytes memory _signature, uint256 rindex) private view returns (bytes memory, uint256) {
124+
// Read signature size
125+
uint256 size;
126+
(size, rindex) = _signature.readUint16(rindex);
127+
128+
// Read dynamic size signature
129+
bytes memory signature;
130+
(signature, rindex) = _signature.readBytes(rindex, size);
131+
return (signature, rindex);
137132
}
138133

139134
/**

0 commit comments

Comments
 (0)