Skip to content

Commit 2e152ba

Browse files
committed
Cause _addSigners to revert if it triggers a totalWeight overflow (#5790)
Signed-off-by: Hadrien Croubois <[email protected]>
1 parent a341850 commit 2e152ba

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,20 @@ abstract contract MultiSignerERC7913Weighted is MultiSignerERC7913 {
130130
_validateReachableThreshold();
131131
}
132132

133+
/**
134+
* @dev See {MultiSignerERC7913-_addSigners}.
135+
*
136+
* In cases where {totalWeight} is almost `type(uint64).max` (due to a large `_totalExtraWeight`), adding new
137+
* signers could cause the {totalWeight} computation to overflow. Adding a {totalWeight} calls after the new
138+
* signers are added ensures no such overflow happens.
139+
*/
140+
function _addSigners(bytes[] memory newSigners) internal virtual override {
141+
super._addSigners(newSigners);
142+
143+
// This will revert if the new signers cause an overflow
144+
_validateReachableThreshold();
145+
}
146+
133147
/**
134148
* @dev See {MultiSignerERC7913-_removeSigners}.
135149
*

test/account/AccountMultiSignerWeighted.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const { getDomain } = require('../helpers/eip712');
66
const { ERC4337Helper } = require('../helpers/erc4337');
77
const { NonNativeSigner, P256SigningKey, RSASHA256SigningKey, MultiERC7913SigningKey } = require('../helpers/signers');
88
const { PackedUserOperation } = require('../helpers/eip712-types');
9+
const { MAX_UINT64 } = require('../helpers/constants');
910

1011
const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('./Account.behavior');
1112
const { shouldBehaveLikeERC1271 } = require('../utils/cryptography/ERC1271.behavior');
@@ -292,5 +293,20 @@ describe('AccountMultiSignerWeighted', function () {
292293
.withArgs(signer1)
293294
.to.not.emit(this.mock, 'ERC7913SignerWeightChanged');
294295
});
296+
297+
it('should revert if total weight to overflow (_setSignerWeights)', async function () {
298+
await expect(this.mock.$_setSignerWeights([signer1, signer2, signer3], [1n, 1n, MAX_UINT64 - 1n]))
299+
.to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedUintDowncast')
300+
.withArgs(64, MAX_UINT64 + 1n);
301+
});
302+
303+
it('should revert if total weight to overflow (_addSigner)', async function () {
304+
await this.mock.$_setSignerWeights([signer1, signer2, signer3], [1n, 1n, MAX_UINT64 - 2n]);
305+
await expect(this.mock.totalWeight()).to.eventually.equal(MAX_UINT64);
306+
307+
await expect(this.mock.$_addSigners([signer4]))
308+
.to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedUintDowncast')
309+
.withArgs(64, MAX_UINT64 + 1n);
310+
});
295311
});
296312
});

0 commit comments

Comments
 (0)