Security
xendune implements multiple layers of security across its 32 smart contracts. All admin operations are controlled by a Gnosis Safe multisig wallet.
Access Control
Role Hierarchy
| Role | Assignment | Permissions |
|---|---|---|
| Owner | Gnosis Safe multisig | Global configuration, role management |
| Admin | Set by Owner | Arbitration, keyword approval, forced operations |
| CS | Set by Owner | Arbitration assistance |
| Factory | Automatic (inter-contract calls) | Product/trade registration |
| Authorized Product | Set by Factory | Deposit deductions |
Core Principle
Owner/admin have no functions to directly withdraw or transfer user funds. All fund flows are triggered through business logic (arbitration resolution, trade settlement, zombie reclamation), with every transfer emitting events for transparency.
Reentrancy Protection
All contracts use uint256-based reentrancy locks (not bool)—best practice for EIP-1167 clones. Clone contracts have storage initialized to zero; bool defaults to false which cannot distinguish "uninitialized" from "unlocked". The uint256 pattern (0→1 in initialize(), then 1→2→1 for lock/unlock) ensures correct behavior in cloned contracts.
Anti-Bot Protection
The noContract modifier blocks smart contract calls (except whitelisted contracts):
modifier noContract() {
if (msg.sender != tx.origin && !settings.isContractWhitelisted(msg.sender))
revert NoContractCalls();
_;
}
This defends against flash loan attacks and automated exploits.
Safe Transfer Pattern
All USDT transfers use ProductLib._safeTransferToUser() with pull payment safety net:
- Attempt direct transfer to recipient
- If transfer fails (e.g., recipient is a contract rejecting transfers), store amount in
pendingWithdrawals[recipient] - Recipient can later call
claimPending()to retrieve funds
This prevents a single failed transfer from blocking entire settlement flow.
Deposit-Based Trust
Merchant deposits create real economic skin in the game:
- Minimum 500 USDT deposit required to list products
- Arbitration can deduct compensation from deposits to buyers
- Deposit balance reflects merchant reliability
- 24-hour cooldown after delisting prevents withdrawal before disputes can be filed
Audit Findings
The protocol has been audited with findings addressed in the following categories:
Input Validation
- Zero-address checks for critical transfer functions
- Zero-amount checks for deposit deductions
- Array length limits (max 10 images, max 5 active products)
Business Logic
- All state-changing functions follow CEI (Checks-Effects-Interactions) pattern
- Swap-and-delete pattern for O(1) array removal without gaps
- Generational archive rotation prevents unbounded array growth
Gas Optimization
- EIP-1167 minimal proxy reduces deployment costs by ~97%
- Warm storage access patterns where applicable
- Bounded loops (max 5 products per seller, max 5 auction slots)
Design Decisions
_clone()function intentionally duplicated across factory contracts for deployment independence- Silent
try/catchin batch operations is intentional—off-chain monitoring detects failures via success count - Storage variable naming follows business domain conventions for readability
Emergency Response
- All admin operations require Gnosis Safe multisig confirmation
- Blacklist functionality can freeze malicious accounts
- Forced delisting can remove problematic products
- Zombie reclamation can recover funds locked in abandoned accounts