
Loading...
Loading
Loading...
LoadingLoading audit report...

WalletGuard.ai, powered by Gestalt Labs
Findings selected for deep verification. Where possible we generated a Solidity proof-of-concept and executed it against a forked mainnet.
contracts/SecondSwap_Marketplace.solFunction: addCoinLines: 200-218The analyzed contract is a vesting token marketplace (SecondSwap) that allows holders of vested token allocations to list, buy, and transfer vesting positions, supported by a network of upgradeable proxy contracts for marketplace logic, vesting management, and whitelist enforcement. The analysis identified 1 critical, 8 high, 12 medium, 10 low, and 4 informational findings across 37 total agent reports. The single most dangerous pattern is the uninitialized proxy implementation, which allows any attacker to take control of the implementation contract directly and manipulate admin-gated logic, combined with pervasive broken referral fee accounting and an authorization flaw that permits token issuers to drain any beneficiary's vesting without consent. The contract in its current state presents material risk to user funds and should not be considered production-ready without resolving the critical and high severity issues identified.
Any attacker can call the setup function directly on the underlying implementation contract (not through the proxy) and configure it with a fake admin address. This gives the attacker control over all admin-protected functions on the implementation, including fee routing and marketplace settings. This is a well-known attack pattern that has resulted in significant losses in real deployments.
A token issuer can call a transfer function and specify any user's vesting allocation as the source, moving that user's tokens to any destination without the user's knowledge or approval. This means a malicious or compromised token issuer can steal the vesting allocations of all beneficiaries registered under their token.
The referral reward system is completely broken: referrers are recorded in transaction logs but never actually receive any payment. The fee collector receives the full fee amount even when a referral was supposed to redirect a portion. Users who refer others receive nothing, while the fee collector collects more than it should.
6 centralization points identified
The restriction is a design choice that limits composability and off-chain access. It does not have a direct exploit path against user funds; the listing flow works as long as marketplace is correctly set.
getVestingTokenAddress()Near-duplicate of finding d9faae49. The onlyMarketplace modifier on a view function is an unnecessary design constraint. Retained with its own FindingId. No active fund loss path.
getVestingTokenAddress()Admin can assign multiple owners to the same token, creating conflicting vesting authority. This is a design flaw requiring admin action to trigger and does not have a direct trustless exploit path.
setTokenOwner()The one-directional constraint on whitelist capacity is an administrative design limitation, not a security vulnerability with a fund-loss path.
setMaxWhitelist()Token issuers are trusted by protocol design, but the absence of bounds allows them to freeze all sales (0%) or enable over-selling (>10000%) for their token. This is a privileged role risk the buyer should know about.
setMaxSellPercent()Near-duplicate of finding fe23a460. The bounds issue on setMaxSellPercent is a centralization risk controlled by the token issuer role. Retained as a separate classification note due to distinct FindingId.
setMaxSellPercent()An attacker exploits the missing disableInitializers() on SecondSwap_Marketplace to call initialize() directly on the implementation contract, setting a malicious marketplaceSetting address. Combined with single-step admin transfer in MarketplaceSetting, the attacker can configure fee collectors and admin addresses on the implementation. While this affects the implementation rather than the proxy, any integrators or tools interacting with the implementation contract directly (rather than through the proxy) will be served malicious responses, and the implementation can be used as a launchpad for further confusion attacks.
An attacker lists a vesting position accepting an ERC-777-compatible payment token as currency. When spotPurchase is called, _handleTransfers triggers safeTransferFrom on the currency token before listing.balance is updated. The ERC-777 receive hook on the attacker's contract re-enters spotPurchase. Because listing.balance has not yet been decremented, the same tokens can be purchased multiple times for the price of one, draining the seller's entire vesting allocation. The doesFunctionExist staticcall false-positive issue also enables a malicious token with a fallback function to pass the validation check, widening the attack surface.
A seller (or an attacker who controls a listing) sets discountPct to 10000 (100%) for either FIX or LINEAR discount type, which is not prevented by input validation. For LINEAR type at full purchase amount, the computed price is zero, allowing tokens to be acquired for free or near-free. The missing upper bound on discountPct in listVesting directly enables this, and the integer division precision loss in _getDiscountedPrice compounds the effect for partial amounts.
| Agent | Status | Findings | Severity | Confidence | Duration | Coverage |
|---|---|---|---|---|---|---|
| reentrancy | success | 8 | 2H2M | 77% | 1.6m | Cross-function reentrancy in spotPurchase and unlistVesting, CEI pattern compliance across all state-modifying functions, ERC-777 callback reentrancy via currency token transfer hooks, Fee calculation and token transfer accounting in _handleTransfers, Sell limit bypass in VestingManager.listVesting, Referral fee distribution logic, Access control on admin functions, Vesting transfer and release rate calculations in StepVesting, Whitelist bypass possibilities, Proxy/upgradeable pattern safety (Initializable usage), Integer overflow/underflow with Solidity 0.8 defaults, Read-only reentrancy on view functions |
| access control | success | 12 | 2M1L | 81% | 1.9m | Access control on admin functions (addCoin, setMarketplaceSettingAddress, setAdmin, etc.), Initializer protection for upgradeable contracts (Marketplace, VestingDeployer, VestingManager), Ownership transfer patterns (single-step vs two-step), Token transfer logic and fee calculations in _handleTransfers, Referral reward distribution logic, Purchase validation logic in _validatePurchase, Discount calculation overflow/underflow in _getDiscountedPrice, Reentrancy patterns in spotPurchase and unlistVesting (CEI pattern), Sell limit calculation and maxSellPercent bypass in VestingManager.listVesting, Whitelist access control in SecondSwap_Whitelist, VestingDeployer token owner verification, StepVesting claim and transfer logic, getVestingTokenAddress onlyMarketplace restriction impact, Penalty fee denomination mismatch (ether vs USDT decimals), Event emission completeness, tx.origin usage (none found), Signature/EIP-712 patterns (none present), delegatecall patterns (only standard OZ proxy, no user-controlled delegatecall), Cross-chain replay (not applicable - no chain ID handling needed for this protocol type), Integer overflow/underflow in Solidity 0.8+ (checked arithmetic) |
| economic | success | 13 | 1H2M3L | 81% | 2.3m | Flash loan attack vectors on listing/purchase price calculations, Oracle manipulation - no external price oracle used, internal price set by sellers, Reentrancy in spotPurchase, unlistVesting, claim - CEI pattern analysis, Access control on all admin functions and marketplace-only functions, Fee calculation correctness in _handleTransfers including referral logic, Integer overflow/underflow with Solidity 0.8.24 built-in protection, Precision loss in price calculations involving decimals and division, Sell limit enforcement in VestingManager.listVesting, Token transfer patterns using SafeERC20, Whitelist bypass vectors, Vesting transfer authorization chain (VestingDeployer -> StepVesting -> VestingManager), SINGLE vs PARTIAL listing type enforcement, Penalty fee calculation and payment flow, ERC1967 proxy upgrade safety - initialize() has initializer modifier, MEV/sandwich exposure - listings have seller-set prices, not DEX swap mechanism, Governance attacks - no governance token mechanism present, doesFunctionExist staticcall reliability, stepDuration integer division edge cases, Duplicate token owner assignment in VestingDeployer |
| logic validation | success | 10 | 1H1M3L | 80% | 2.1m | Input validation on listVesting parameters (price, amount, discount, currency), Referral fee calculation and transfer logic in _handleTransfers, Arithmetic precision in price calculations and discount computations, State machine transitions: LIST -> SOLDOUT / DELIST, Access control on marketplace, vesting manager, and settings contracts, Sell limit enforcement in VestingManager.listVesting, transferVesting releaseRate recalculation correctness, ERC-4626 style reentrancy patterns (N/A - not a vault), onlyMarketplace modifier on view function getVestingTokenAddress, Whitelist address validation in private listings, Upgrade safety - initializer patterns with Initializable, Unbounded loops in createVestings, Timestamp manipulation in minListingDuration penalty check, Zero-address validation in constructors and initializers, discountPct upper bound validation, Integer overflow/underflow in Solidity 0.8.24 (checked arithmetic), SafeERC20 usage for token transfers, SINGLE vs PARTIAL listing type enforcement |
| code quality | success | 12 | 83% | 1.8m | Reentrancy in purchase/unlist flows, Access control on admin functions, Fee calculation arithmetic and precision, Referral payment logic, Vesting transfer and claim logic, Sell limit enforcement in VestingManager, ERC-1967 proxy compliance, Integer overflow/underflow in Solidity 0.8, Whitelist validation logic, Discount calculation correctness, SINGLE vs PARTIAL listing type validation, Initialization security in upgradeable contracts, SafeERC20 usage, Event emission completeness | |
| compiler bugs | success | 8 | 1L | 78% | 1.3m | Reentrancy patterns in spotPurchase, unlistVesting, and _handleTransfers, Access control on all admin functions (addCoin, setMarketplaceSettingAddress, setSellable, etc.), Referral fee calculation and transfer logic in _handleTransfers, Discount price calculation overflow/underflow in _getDiscountedPrice, Listing validation logic in _validatePurchase and listVesting, Vesting transfer and creation logic in SecondSwap_StepVesting, Integer arithmetic precision in claimable() and _createVesting(), ERC1967 proxy upgrade safety and initializer patterns, onlyMarketplace modifier interaction with getVestingTokenAddress, Penalty fee logic in unlistVesting, Whitelist validation bypass possibilities, Compiler bug patterns for pragma ^0.8.24 (no applicable known bugs) |
| assembly safety | success | 10 | 1H2M1L | 79% | 1.8m | Full source code scan for non-ASCII characters and Unicode homoglyphs in identifiers, strings, and comments, Inline assembly blocks - none present in the analyzed contracts, Reentrancy patterns in spotPurchase, unlistVesting, and listVesting, Access control on admin-only functions across all contracts, Fee calculation arithmetic in _handleTransfers and _getDiscountedPrice, Referral reward logic and actual token transfer mechanics, Integer overflow/underflow in Solidity 0.8.x (built-in protection active), Vesting accounting in listVesting/unlistVesting/completePurchase flow, Precision loss in baseAmount calculations with different token decimals, LINEAR and FIX discount type boundary conditions, ERC1967 proxy upgrade safety and storage slot collisions, Whitelist deployment and validation logic, SINGLE vs PARTIAL listing type enforcement, transferVesting claimed amount tracking in SecondSwap_StepVesting, Initialization security in upgradeable contracts (Initializable pattern) |
| l2 specific | success | 13 | 1H2M2L | 79% | 1.8m | Reentrancy in spotPurchase and unlistVesting (CEI pattern check), Access control on all admin functions, Fee calculation arithmetic in _handleTransfers, Referral fee transfer logic, Linear and fixed discount calculations in _getDiscountedPrice, Sell limit calculation in VestingManager.listVesting, Transfer vesting authorization in VestingDeployer, Vesting creation and stepsClaimed handling in StepVesting, Penalty fee currency and amount validation, doesFunctionExist staticcall security, Whitelist access control, ERC1967 proxy upgrade safety (initialize function protection), Integer overflow/underflow in Solidity 0.8.x (built-in protection), SafeERC20 usage for token transfers, L2-specific patterns (no L2 imports or predeploy addresses found), Chain ID usage (none found), Token support mapping and addCoin, Marketplace freeze modifier, SINGLE vs PARTIAL listing type validation |
| upgrade | success | 15 | 1C1H2M | 84% | 2.0m | ERC-1967 proxy pattern and initializer safety for all upgradeable contracts, Storage layout and gap arrays in upgradeable contracts, Access control on admin functions across all contracts, Fee calculation logic in _handleTransfers and referral distribution, Discount price calculation for LINEAR and FIX types, Sell limit calculation logic in VestingManager.listVesting, Token transfer patterns and SafeERC20 usage, Listing validation logic in _validatePurchase, Vesting transfer and claim logic in StepVesting, Whitelist mechanism and private sale logic, Integer overflow/underflow in Solidity 0.8, Reentrancy patterns in purchase and unlist flows, Constructor parameters validation in StepVesting, Division by zero risks in vesting calculations, UUPS vs Transparent proxy upgrade authorization |
This automated audit has inherent limitations. The following areas are not covered.
This report is an automated point-in-time assessment and does not guarantee protection against all possible attacks. It does not cover off-chain components, economic modeling, or business logic correctness unless explicitly noted. Changes to the contract after the audit commit are not reviewed. This is not financial or legal advice. WalletGuard, powered by Gestalt Labs, provides this analysis as-is with no warranty of completeness.
[](https://walletguard.ai/audit/4ce95f58-3c58-46f7-9a2a-12fe08714970)
<a href="https://walletguard.ai/audit/4ce95f58-3c58-46f7-9a2a-12fe08714970"> <img src="https://walletguard.ai/api/badge/4ce95f58-3c58-46f7-9a2a-12fe08714970" alt="WalletGuard Audit Badge" /> </a>