πŸ” Contract AuditSecurity Findings

Audit Findings

Complete list of findings from the Abba Baba V1 contract security audit.


Summary

SeverityCountStatus
Critical0β€”
High0β€”
Medium2Fixed βœ…
Low3Fixed βœ… (L-01, L-03) / Acknowledged (L-02, by design)
Informational5Best 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.sol
  • AbbababaScoreV1.sol
  • AbbababaResolverV1.sol
  • ReviewerPaymentV1.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 donationAmount mapping
  • No value extraction possible

Fix Applied:

  • Added ReentrancyGuardUpgradeable inheritance to AbbababaScoreV1
  • Added nonReentrant modifier to donateWithPermit() for defense-in-depth
  • Added __ReentrancyGuard_init() to initialize() 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 = 20 constant
  • Added _grantRole override that checks getRoleMemberCount(ARBITRATOR_ROLE) < MAX_ARBITRATORS before 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.00

I-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: 35

False Positives Dismissed

  1. divide-before-multiply in getRegistrationPoints() β€” Intentional precision loss for sub-dollar amounts
  2. divide-before-multiply in distributePayments() β€” Dust is correctly handled and distributed
  3. incorrect-equality in _submitResolution() β€” Enum comparison is safe
  4. timestamp warnings β€” Acceptable for hour+ time windows

SWC Registry Checklist

SWCVulnerabilityStatus
SWC-100Function Default VisibilityPASS
SWC-101Integer Overflow/UnderflowPASS (0.8.24)
SWC-102Outdated CompilerPASS
SWC-103Floating PragmaFIXED
SWC-104Unchecked Call ReturnPASS (SafeERC20)
SWC-106Unprotected SELFDESTRUCTPASS (none)
SWC-107ReentrancyPASS (nonReentrant)
SWC-112Delegatecall to UntrustedPASS (UUPS safe)
SWC-113DoS with Failed CallPASS
SWC-114Transaction Order DependencePASS
SWC-115tx.origin AuthorizationPASS (uses msg.sender)
SWC-116Block TimestampINFO (acceptable)
SWC-117Signature MalleabilityPASS (EIP-2612)
SWC-128DoS Block Gas LimitPASS (bounded loops)

See Methodology for complete details on tools and processes used.