From 02a580810f2777bb48c34f81115c4085be43c4b8 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Thu, 19 Mar 2026 16:52:35 -0400 Subject: [PATCH 1/2] fix: review feedback on PR #67 - Fix contest threshold integer division rounding: multiply contestCount by PERCENTAGE_BASE instead of dividing the right-hand side, preventing truncation from silently lowering the effective veto threshold - Change _deduct visibility from private to internal for consistency with other helper functions - Fix gendered language in AlreadyContestedByMember NatSpec - Remove empty src/contracts/modification.txt --- src/contracts/SafetyNet.sol | 7 ++++--- src/contracts/modification.txt | 0 src/interfaces/ISafetyNet.sol | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) delete mode 100644 src/contracts/modification.txt diff --git a/src/contracts/SafetyNet.sol b/src/contracts/SafetyNet.sol index 9061dbe..6646b50 100644 --- a/src/contracts/SafetyNet.sol +++ b/src/contracts/SafetyNet.sol @@ -279,8 +279,9 @@ contract SafetyNet is ISafetyNet, ReentrancyGuard, OwnableUpgradeable { emit WithdrawalContested(_requestId, _request.owner, block.timestamp); - // Check if consensus on contestation has been reached after this contestation - if (_request.contestCount > memberCount * threshold / PERCENTAGE_BASE) { + // Multiply contestCount by PERCENTAGE_BASE instead of dividing the + // right-hand side, so integer truncation cannot lower the threshold. + if (_request.contestCount * PERCENTAGE_BASE > memberCount * threshold) { isVetoed[_requestId] = true; // Vetoed because more than contestThreshold% of the members have contested emit WithdrawalVetoed(_requestId, _request.owner, block.timestamp); @@ -554,7 +555,7 @@ contract SafetyNet is ISafetyNet, ReentrancyGuard, OwnableUpgradeable { /// @dev Deducts `_amount` from a member’s withdrawable balance and the Safety Net’s total balance. /// Reverts with `NotWithdrawable` if balance is insufficient. - function _deduct(uint256 _safetyNetId, address _member, uint256 _amount) private { + function _deduct(uint256 _safetyNetId, address _member, uint256 _amount) internal { if (memberWithdrawableBalance[_safetyNetId][_member] < _amount) { revert NotWithdrawable(); } diff --git a/src/contracts/modification.txt b/src/contracts/modification.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/interfaces/ISafetyNet.sol b/src/interfaces/ISafetyNet.sol index e65aef2..19b23ab 100644 --- a/src/interfaces/ISafetyNet.sol +++ b/src/interfaces/ISafetyNet.sol @@ -136,7 +136,7 @@ interface ISafetyNet { /// @notice Thrown when trying to create a duplicate Safety Net error AlreadyExists(); - /// @notice Thrown when a user is trying to contest a request that he has already contested + /// @notice Thrown when a member is trying to contest a request that they have already contested error AlreadyContestedByMember(); /// @notice Thrown when the Safety Net ID is not found From 827eef8e1384c767bbdb409082c5194d6302dd80 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Thu, 19 Mar 2026 16:55:53 -0400 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20typo=20in=20NatSpec=20=E2=80=94=20re?= =?UTF-8?q?deemeRatio=20=E2=86=92=20redeemRatio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/interfaces/ISafetyNet.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/ISafetyNet.sol b/src/interfaces/ISafetyNet.sol index 19b23ab..3dc34d5 100644 --- a/src/interfaces/ISafetyNet.sol +++ b/src/interfaces/ISafetyNet.sol @@ -214,7 +214,7 @@ interface ISafetyNet { /// @notice Thrown when epoch duration is invalid error InvalidEpochDuration(); - /// @notice Thrown when redeemeRatio is out of valid range + /// @notice Thrown when redeemRatio is out of valid range error InvalidRatio(); /// @notice Thrown when small withdraws limit is invalid