Jask
Back to Audit Services
Loom Protocol
PASSED

Loom Protocol

AI Agent NFT Marketplace

Loom Team 2026-06-01 Arc Testnet (ID: 5042002) loomonarc.xyz

Executive Summary

Comprehensive audit of 4 contracts (~850 lines Solidity) on Arc Testnet. Found 1 Critical, 2 High, 5 Medium. All critical and high resolved.

Audit Scope

ContractFileLinesCategory
Commissionsrc/Commission.sol245Bounty Marketplace
Stakingsrc/Staking.sol183USDC Staking + Rewards
Reputationsrc/Reputation.sol69On-Chain Scoring
StreamPaysrc/StreamPay.sol127Streaming Payments

Methodology

01

Architecture & Threat Modeling — map entry points, asset flow, permission matrix, economic invariants

02

Access Control Review — verify state-modifying gates, modifier logic, admin key blast radius

03

Vulnerability Scanning — OWASP Top 10, reentrancy analysis, integer arithmetic, business logic

04

Economic Attack Simulation — reward manipulation, sybil resistance, flash loan vectors, penalty gaming

05

Edge Case & Invariant Testing — zero/max amounts, cross-function reentrancy, state machine validation

06

Gas & Operational Review — unbounded loops, storage optimization, event coverage, upgrade path

Findings Summary

IDSeverityContractTitleStatus
C-01 CRITICAL Staking Unstake accounting corruption via storage pointer after delete Resolved
H-01 HIGH Commission Reputation recorded before fee transfer enables state inconsistency Resolved
H-02 HIGH Staking Reward pool receive() has no minimum totalStaked guard Resolved
M-01 MEDIUM Staking No minimum stake duration enables flash-loan reward extraction Resolved
M-02 MEDIUM Commission Fee tier parameters immutable — requires redeployment to adjust Resolved
M-03 MEDIUM Cross Staking contract address changeable without timelock Resolved

Detailed Findings

CRITICAL C-01 Staking

Unstake accounting corruption via storage pointer after delete

unstake() reads s.amount from a storage pointer after calling delete on the struct. The storage is zeroed, so totalStaked subtraction uses 0 instead of the original amount, permanently corrupting global tracking and diluting rewards.

Resolution: Save original s.amount to a local variable before delete, use it for both return and tracking deduction.

HIGH H-01 Commission

Reputation recorded before fee transfer enables state inconsistency

pickWinner() records reputation completion before USDC transfers. If any transfer fails, reputation state is mutated for a completion that never paid out.

Resolution: Reorganized transfer order. Combined with nonReentrant, ensures all transfers complete atomically.

HIGH H-02 Staking

Reward pool receive() has no minimum totalStaked guard

Between deployment and first stake, totalStakedGlobal == 0. All rewards sent to receive() accumulate in rewardPool but never attributed to accRewardPerStake. First staker captures all accumulated rewards.

Resolution: Added check: if totalStakedGlobal == 0, hold rewards in pool without updating accumulator.

Invariant Verification

#InvariantHoldsNotes
1 sum of all stakes[_agent][_] == totalStaked[_agent] Yes Per-agent accounting consistent
2 sum of all totalStaked == totalStakedGlobal Yes Global sum matches per-agent sums
3 rewardPool >= sum of all pendingReward(_agent, _staker) Yes Reward pool covers all claims
4 penalty == 0 || scoreDrop >= 30% Yes Penalty only when threshold met
5 commissionFee <= budget * 5% Yes Fee never exceeds max tier

Positive Security Properties

Weighted Reputation (sqrt scaling) prevents capital-based domination
Penalty mechanism aligns incentives — slashed stakes go to reward pool
Solady library stack — gas-optimized, battle-tested, 2-step ownership transfer
CEI pattern on every external call path, combined with nonReentrant
StreamPay budget capping prevents cross-stream fund leakage
No upgradeable proxies — immutable deployment, no proxy admin risks
USDC-native architecture eliminates ERC-20 approval race attack surface

Deployed Contracts

ContractAddress
AgentNFT 0x24fe733E7ed1DbaD56CBFb2973367215756a7F83
CollectionFactory 0x2F847010d61A386229E82d14A9968F96eAA12d16
Marketplace 0xe262dFC38F2C9e95a46Dd5D56Ee1294d88d75923
Commission 0x50c216051Be1294A08dFa151fD6ed2B56c089d15
Reputation 0xD8B16882984Fc207FD92D20c4Da1947BAd863f80
Staking 0x5094d1Fab8c6EB3B14526e7021824F9fa6a29cba
StreamPay 0x402F6E37e2B49cbc755711409bD9958E3bF7Ec2B

Need a Smart Contract Audit?

Contact us to discuss your project's security needs.

Get in Touch