Audit Findings
Complete list of findings from the Abba Baba V1 contract security audit.
Summary
| Severity | Count | Status |
|---|---|---|
| Critical | 0 | β |
| High | 0 | β |
| Medium | 2 | Fixed β |
| Low | 3 | Fixed β (L-01, L-03) / Acknowledged (L-02, by design) |
| Informational | 5 | Best practice |
Medium Severity
M-01: Missing Storage Gaps for UUPS Upgrades
Status: Fixed
Location: All 4 contracts
Description: Upgradeable contracts using the UUPS pattern should include storage gaps to reserve space for future state variables. Without gaps, adding new variables in V2 could corrupt storage layout.
Impact: Storage collisions during future upgrades could corrupt contract state.
Fix Applied:
// Reserve 50 slots for future upgrades
uint256[50] private __gap;Added to:
AbbababaEscrowV1.solAbbababaScoreV1.solAbbababaResolverV1.solReviewerPaymentV1.sol
M-02: Floating Pragma Version
Status: Fixed
Location: All contracts, line 2
Description:
Contracts used ^0.8.24 which allows compilation with any compatible compiler version. For production deployments, locking the exact version ensures deterministic builds.
Impact: Different compiler versions could produce different bytecode.
Fix Applied:
// Before
pragma solidity ^0.8.24;
// After
pragma solidity 0.8.24;Low Severity
L-01: Reentrancy in donateWithPermit (Benign)
Status: Fixed β (Feb 13, 2026)
Location: AbbababaScoreV1.sol:517-544
Description:
The donateWithPermit() function updates state after calling external permit(). While technically a reentrancy pattern, no exploit path exists because:
permit()is a standard EIP-2612 call to USDC- Only affects callerβs own
donationAmountmapping - No value extraction possible
Fix Applied:
- Added
ReentrancyGuardUpgradeableinheritance toAbbababaScoreV1 - Added
nonReentrantmodifier todonateWithPermit()for defense-in-depth - Added
__ReentrancyGuard_init()toinitialize()function - Added
reinitializeV5()for upgrade-safe initialization (OZ v5 namespaced storage)
// Before
) external whenNotPaused {
// After
) external nonReentrant whenNotPaused {L-02: Precision Loss in Donation Points
Status: Acknowledged (By Design)
Location: AbbababaScoreV1.sol:427
Description: Donations under $1 result in 0 registration points due to integer division:
points += int256((donationAmount[agent] / 1e6) * uint256(DONATION_POINTS_PER_DOLLAR))Assessment: This is intentional behavior. Fractional dollar donations donβt earn points. The minimum meaningful donation is $1 for 10 points.
L-03: Unbounded Arbitrator Loop
Status: Fixed β (Feb 13, 2026)
Location: AbbababaEscrowV1.sol:837-844
Description:
The _getArbitrators() function iterates over all addresses with ARBITRATOR_ROLE. With excessive arbitrators, this could hit gas limits.
Fix Applied:
- Added
MAX_ARBITRATORS = 20constant - Added
_grantRoleoverride that checksgetRoleMemberCount(ARBITRATOR_ROLE) < MAX_ARBITRATORSbefore granting
uint256 public constant MAX_ARBITRATORS = 20;
function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {
if (role == ARBITRATOR_ROLE) {
require(getRoleMemberCount(ARBITRATOR_ROLE) < MAX_ARBITRATORS, "Max arbitrators reached");
}
return super._grantRole(role, account);
}Informational
I-01: ReviewerPaymentV1 Missing Interface Inheritance
Location: ReviewerPaymentV1.sol:28
Description: Contract should explicitly inherit IReviewerPayment interface.
Recommendation: Add is IReviewerPayment to contract declaration.
I-02: Parameter Naming Convention
Location: Initialize functions across all contracts
Description: Underscore-prefixed parameters (_treasury, _usdc) flagged by Slither.
Assessment: This is standard Solidity convention. No action needed.
I-03: Magic Numbers in Fee Constants
Location: AbbababaEscrowV1.sol:92-93
Description: Large literals like 1000000 could use scientific notation for readability.
// Current
uint256 public constant MIN_TIER2_FEE = 1000000; // $1.00
// Recommended
uint256 public constant MIN_TIER2_FEE = 1e6; // $1.00I-04: High Cyclomatic Complexity
Location: AbbababaEscrowV1._executeResolution()
Description: Complexity score of 14 due to multiple outcome branches (BuyerRefund, SellerPaid, Split) and tier calculations.
Assessment: Acceptable given the functionβs responsibility. Well-tested with full coverage.
I-05: Event Ordering in Resolver
Location: AbbababaResolverV1._submitResolution()
Description: Event DisputeResolutionSubmitted emitted after external call to escrow contract.
Assessment: No security impact. Consider emitting before external call for consistency.
Static Analysis Results
Slither Summary
Contracts analyzed: 43
Detectors run: 101
Results found: 38
High: 0
Medium: 0 (after review - false positives)
Low: 3
Informational: 35False Positives Dismissed
- divide-before-multiply in
getRegistrationPoints()β Intentional precision loss for sub-dollar amounts - divide-before-multiply in
distributePayments()β Dust is correctly handled and distributed - incorrect-equality in
_submitResolution()β Enum comparison is safe - timestamp warnings β Acceptable for hour+ time windows
SWC Registry Checklist
| SWC | Vulnerability | Status |
|---|---|---|
| SWC-100 | Function Default Visibility | PASS |
| SWC-101 | Integer Overflow/Underflow | PASS (0.8.24) |
| SWC-102 | Outdated Compiler | PASS |
| SWC-103 | Floating Pragma | FIXED |
| SWC-104 | Unchecked Call Return | PASS (SafeERC20) |
| SWC-106 | Unprotected SELFDESTRUCT | PASS (none) |
| SWC-107 | Reentrancy | PASS (nonReentrant) |
| SWC-112 | Delegatecall to Untrusted | PASS (UUPS safe) |
| SWC-113 | DoS with Failed Call | PASS |
| SWC-114 | Transaction Order Dependence | PASS |
| SWC-115 | tx.origin Authorization | PASS (uses msg.sender) |
| SWC-116 | Block Timestamp | INFO (acceptable) |
| SWC-117 | Signature Malleability | PASS (EIP-2612) |
| SWC-128 | DoS Block Gas Limit | PASS (bounded loops) |
See Methodology for complete details on tools and processes used.