Omniscia Nexera Audit
TwoCapPurchaseAmountFacetStorage Manual Review Findings
TwoCapPurchaseAmountFacetStorage Manual Review Findings
TCA-01M: Redundant Limitation of Per Account Softcap
| Type | Severity | Location |
|---|---|---|
| Logical Fault | ![]() | TwoCapPurchaseAmountFacetStorage.sol:L122 |
Description:
The newly introduced softcap per account is presently limited to be less than or equal to the campaign's softCap which is a redundant limitation and requires the user to set a campaign-wide softcap if they wish to solely enforce per-account softcaps.
Impact:
The current behaviour of the code limits the potential valid configurations of the system incorrectly yet does not result in any security vulnerability rendering it to be of informational severity.
Example:
packages/contracts/contracts/internalFacets/purchasePhaseFacets/purchaseAmountFacets/twoCap/TwoCapPurchaseAmountFacetStorage.sol
106function setAndCheckPurchaseAmounts(107 Layout storage l,108 bytes calldata postFractionsAmountData109) internal returns (uint256, uint256, uint256, uint256, uint256) {110 (uint256 softCap, uint256 hardCap, uint256 softCapPerAccount, uint256 hardCapPerAccount) = abi.decode(111 postFractionsAmountData,112 (uint256, uint256, uint256, uint256)113 );114
115 GeneralStorage.Layout storage gs = GeneralStorage.layout();116 uint256 currentId = gs.currentId;117
118 if (hardCap == 0 || softCap > hardCap || softCap > gs.infoForId[currentId].fractionsCreated)119 revert InvalidInputAmounts(currentId, softCap, hardCap);120 if (hardCap > l.maxHardCap) revert HardcapExceedsMaxHardcap(currentId, hardCap, l.maxHardCap);121 if (hardCapPerAccount > hardCap) revert HardcapPerAccountExceedsHardcap(currentId, hardCapPerAccount, hardCap);122 if (softCapPerAccount > softCap) revert SoftcapPerAccountExceedsSoftcap(currentId, softCapPerAccount, softCap);123 if (softCapPerAccount > hardCapPerAccount)124 revert SoftcapPerAccountExceedsHardcapPerAccount(currentId, softCapPerAccount, hardCapPerAccount);125
126 l.softCapForId[currentId] = softCap;127 l.hardCapForId[currentId] = hardCap;128 l.softCapPerAccountForId[currentId] = softCapPerAccount;129 l.hardCapPerAccountForId[currentId] = hardCapPerAccount;130
131 return (currentId, softCap, hardCap, softCapPerAccount, hardCapPerAccount);132}Recommendation:
We advise the softCapPerAccount and softCap relation to be omitted, permitting a non-zero softCapPerAccount to be specified with a zero value softCap.
Alleviation (d682057ecb0e254069773d64f32c068cedb71e2a):
The referenced limitation has been omitted per our recommendation, increasing the number of valid TwoCapPurchaseAmountFacetStorage configurations.
