Loading...

Loading
WalletGuard Audit: EVMBench: 2026-01-tempo-feeamm | Score: 1.0/10

high(36)

medium(33)

low(3)
Gas Optimizations(1)

Attack Chain Analysis

Single-Token Pool Bootstrap to Donation Draincritical

An attacker first calls mint() with only validatorToken, creating a pool with zero reserveUserToken (Finding 1). Because the contract accepts single-token initialization, no userToken is locked. The attacker then directly transfers a large amount of userToken to the contract address, inflating pool.reserveUserToken without issuing proportional liquidity shares. On the next mint() call, the weighted liquidity formula uses the inflated reserveUserToken in the denominator but only the attacker's small new validatorToken deposit in the numerator, yielding disproportionate LP shares. The attacker burns these shares via burn() (Finding 4) to extract both tokens. The zero-amount burn griefing path (Finding 15) further enables the attacker to manipulate the totalSupply/reserve ratio before executing the drain, maximizing extraction. Combined severity is critical because each step reinforces the next.

Broken AMM invariant: mint() function fails to enforce equal-value deposits, allowing first minter to drain entire pool via donation attackburn() function does not validate that calculated amountUserToken and amountValidatorToken are both non-zero, allowing zero-amount transfers and silent pool drains where LP tokens are burned without reducing reservesDivision-before-multiplication rounding in _calculateBurnAmounts causes liquidity providers to receive systematically less than their fair share, draining LP value to contract over time
Inverted Fee Formula Combined with Identical-Token Pool Manipulationcritical

The inverted fee formula in rebalanceSwap() (Finding 6) means users pay less than fair value for userToken. An attacker can amplify this by first calling executeFeeSwap with identical token addresses (Finding 5/25) to inject tokens into a self-referential pool, manipulating the reserve ratios. The attacker then calls rebalanceSwap on the manipulated pool to extract validatorToken at the discounted rate. Because reserveUserToken is artificially inflated by the identical-token swap, the pool has more apparent liquidity, and the inverted fee formula allows the attacker to drain it faster than the fee revenue can compensate.

Unconditional +1 offset in rebalanceSwap() amountIn calculation causes systematic overpayment and breaks economic reciprocityNo validation that poolId tokens are distinct from each other; identical token addresses allowed, breaking pool invariantMissing input validation on token addresses in mint and burn functions allows pool to be created for identical tokens, violating intended behavior
Zero-Burn Griefing to totalSupply Collapse Enabling LP Share Inflationcritical

An attacker holding minimal LP tokens (as few as 1 wei, obtainable via the single-token mint vulnerability in Finding 1) can repeatedly call burn() with liquidity=1. If pool.reserveUserToken or reserveValidatorToken is small relative to totalSupply, _calculateBurnAmounts() returns (0, 0) (Finding 15, Finding 24). The burn succeeds, decrementing totalSupply and liquidityBalances[attacker] by 1 each call, while reserves remain unchanged. This asymmetric decay is compounded by the mint() formula (Finding 13) which divides by totalSupply: once totalSupply approaches zero, any subsequent mint() call either reverts on division by zero or mints an astronomically large share, allowing the attacker to claim the entire reserve in one final burn.

burn() function does not validate that calculated amountUserToken and amountValidatorToken are both non-zero, allowing zero-amount transfers and silent pool drains where LP tokens are burned without reducing reservesBurn can revert due to rounding when amountUserToken or amountValidatorToken computation results in zeroDivision-before-multiplication in mint() causes precision loss and share underpricing on first depositBroken AMM invariant: mint() function fails to enforce equal-value deposits, allowing first minter to drain entire pool via donation attack
Unchecked ERC20 Return Value Enabling Reserve-Balance Divergence for Silent Drainhigh

All transfer() and transferFrom() calls lack return value checks (Finding 16). If a token's transfer fails silently (returns false instead of reverting), the pool's reserve counters are decremented as if the transfer succeeded. Combined with the fee formula asymmetry (Findings 2, 6, 7), an attacker can repeatedly trigger silent transfer failures during outbound transfers in executeFeeSwap(), accumulating reserve decrements without actual token outflows. The resulting reserve undercount makes the pool appear less liquid than it is, suppressing the prices computed by the mint() weighted formula and allowing subsequent LPs to mint shares cheaply. These cheaply-minted shares can then be burned to claim the real (underdecremented) token balance.

Missing return value check on ERC20 transfer() calls allows silent failure, causing pool reserves to diverge from actual balancesFee calculation asymmetry between executeFeeSwap (M=9970, 0.3% fee) and rebalanceSwap (N=9985, 0.15% fee adjustment) enables arbitrage extraction of protocol value and breaks fee symmetryUnconditional +1 offset in rebalanceSwap() amountIn calculation causes systematic overpayment and breaks economic reciprocity
Single-Token Pool Initialization + Donation Attack + Zero-Value Burn Griefingcritical

Step 1: Attacker calls mint() with 1 wei validatorToken to initialize a pool (exploiting the single-token init flaw). The pool has reserveUserToken=0 and tiny reserveValidatorToken. Step 2: Attacker directly transfers a large amount of userToken to the contract address, inflating the pool's effective userToken balance without updating reserveUserToken (the reserve only updates on mint/swap calls). Step 3: Attacker calls mint() again with minimal validatorToken; the weighted-denominator formula assigns disproportionately large liquidity shares because the reserve ratio is skewed. Step 4: Attacker calls burn() to extract both tokens, draining the pool. If other LPs have deposited in the interim, they lose everything. As an alternative attack vector, attacker calls burn(1) repeatedly to drain totalSupply toward zero without removing reserves, causing future mint() pricing to break catastrophically.

Broken AMM invariant: mint() function fails to enforce equal-value deposits, allowing first minter to drain entire pool via donation attackburn() function does not validate that calculated amountUserToken and amountValidatorToken are both non-zero, allowing zero-amount transfers and silent pool drains where LP tokens are burned without reducing reservesDivision-before-multiplication rounding in _calculateBurnAmounts causes liquidity providers to receive systematically less than their fair share, draining LP value to contract over time
Inverted rebalanceSwap Fee Formula + Fee Asymmetry Arbitrage = Continuous Reserve Draincritical

The inverted fee formula in rebalanceSwap() (Finding 6) means users pay less than fair value for every userToken received. Combined with the fee asymmetry between executeFeeSwap (0.3% fee) and rebalanceSwap (effectively a discount), an attacker can: (1) Call executeFeeSwap to convert 10,000 userToken into 9,970 validatorToken, paying 30 units as fee. (2) Call rebalanceSwap requesting 9,970 userToken output; the inverted formula computes amountIn = (9970 * 9985) / 10000 + 1 = 9,956 validatorToken. Attacker pays 9,956 and receives 9,970 userToken. (3) Net result after round trip: started with 10,000 userToken, now has 9,970 + 14 = net position showing 14 validatorToken profit. Repeated at scale, this drains all validatorToken reserves. The protocol's own fee structure enables the attack with no special privileges required.

Unconditional +1 offset in rebalanceSwap() amountIn calculation causes systematic overpayment and breaks economic reciprocityFee calculation asymmetry between executeFeeSwap (M=9970, 0.3% fee) and rebalanceSwap (N=9985, 0.15% fee adjustment) enables arbitrage extraction of protocol value and breaks fee symmetryFee calculation in executeFeeSwap() uses incorrect constant M (99.7%) instead of N (99.85%), causing protocol to lose fees on every swap
Identical Token Swap + Pool State Corruption + Reserve Inflationcritical

executeFeeSwap and rebalanceSwap lack the userToken != validatorToken check present in mint/burn. An attacker calls executeFeeSwap(TOKEN_A, TOKEN_A, X): the contract takes X TOKEN_A from the caller, adds X to reserveUserToken, subtracts 0.997X from reserveValidatorToken, and sends 0.997X TOKEN_A back. Net: attacker spent 0.003X tokens, pool's reserveUserToken increased by X while reserveValidatorToken decreased by 0.997X. Repeating this skews the reserve ratio arbitrarily. Once the reserve ratio is sufficiently distorted, the attacker calls mint() with minimal validatorToken, receiving inflated liquidity shares due to the skewed denominator in the weighted formula. Finally, burn() drains the pool at the artificially inflated ratio, stealing from all honest LPs.

No validation that poolId tokens are distinct from each other; identical token addresses allowed, breaking pool invariantMissing input validation on token addresses in mint and burn functions allows pool to be created for identical tokens, violating intended behaviorBroken AMM invariant: mint() function fails to enforce equal-value deposits, allowing first minter to drain entire pool via donation attack
Zero-Value Burn Griefing + totalSupply Exhaustion + mint() Division-by-Zero DoScritical

An attacker who holds any LP tokens calls burn(1) repeatedly. Each call burns 1 unit of liquidity and (due to rounding in _calculateBurnAmounts) returns 0 tokens to the attacker. The pool's totalSupply and the attacker's liquidityBalance both decrease by 1 each call. If the attacker has 10^6 LP tokens, they can reduce totalSupply by 10^6 with no token cost beyond gas. When totalSupply reaches 0 while reserves remain non-zero, subsequent mint() calls in the non-initial branch compute liquidity = (amountValidatorToken * 0) / denom = 0, then hit the require(liquidity != 0) check and revert. The pool becomes permanently bricked: burn() requires liquidity > 0 and liquidityBalance >= liquidity, but if the attacker drained all LP tokens, no one can burn. The reserves are permanently locked.

burn() function does not validate that calculated amountUserToken and amountValidatorToken are both non-zero, allowing zero-amount transfers and silent pool drains where LP tokens are burned without reducing reservesBurn can revert due to rounding when amountUserToken or amountValidatorToken computation results in zeroDivision-before-multiplication rounding in _calculateBurnAmounts causes liquidity providers to receive systematically less than their fair share, draining LP value to contract over time
Unchecked ERC20 Return Value + Reserve Divergence + Insolvency Cascadecritical

The contract does not use SafeERC20 and does not check return values from transfer/transferFrom. If a token's transfer() returns false (e.g., USDC with OFAC blacklisting, or a paused token), the reserve update still executes. For example, in executeFeeSwap: transferFrom(sender, contract, amountIn) fails silently -> pool.reserveUserToken += amountIn (pool believes it received tokens it did not). On the validatorToken transfer: IERC20(validatorToken).transfer(sender, amountOut) fails silently -> pool.reserveValidatorToken -= amountOut (pool believes it sent tokens it did not). The pool now tracks phantom reserves. Combined with the fee asymmetry, an attacker can exploit the phantom reserves by calling rebalanceSwap against the inflated userToken reserve, receiving real validatorToken while paying nothing. This causes direct fund loss for all honest LPs.

Missing return value check on ERC20 transfer() calls allows silent failure, causing pool reserves to diverge from actual balancesUnconditional +1 offset in rebalanceSwap() amountIn calculation causes systematic overpayment and breaks economic reciprocityFee calculation asymmetry between executeFeeSwap (M=9970, 0.3% fee) and rebalanceSwap (N=9985, 0.15% fee adjustment) enables arbitrage extraction of protocol value and breaks fee symmetry
Uint256 Overflow in Intermediate Arithmetic + Bypassed _requireU128 Check = Silent Fund Losscritical

In Solidity 0.7.6 (which this contract uses), arithmetic does not have implicit overflow protection. In executeFeeSwap, amountOut is computed as (amountIn * M) / SCALE before _requireU128(amountIn) is called. If a user supplies amountIn close to type(uint256).max / M (approximately 1.16e73), the multiplication amountIn * M silently overflows uint256 and wraps to a small value. After division by SCALE, amountOut is tiny. The user's transferFrom succeeds for the huge amountIn, pool.reserveUserToken is incremented by the huge value (which also overflows uint128 unless _requireU128 catches it), and the user receives nearly nothing. The overflow check sequence is: compute amountOut (may overflow), then check _requireU128(amountIn) and _requireU128(amountOut). Since amountOut wraps to a small number, it passes the uint128 check, but the user already transferred a massive amount. Combined with the identical-token-address bug, an attacker can construct overflow scenarios that corrupt both reserves simultaneously.

Unsafe downcast of amountIn and amountOut to uint128 without prior bounds validation allows silent truncation if values exceed uint128.maxUnsafe down-cast from uint256 to uint128 in rebalanceSwap allows overflow check bypass, enabling attacker to corrupt pool reserves and lock liquidityNo validation that poolId tokens are distinct from each other; identical token addresses allowed, breaking pool invariant
K-Invariant Absence + Fee Asymmetry + Mint Mispricing = LP Value Extractioncritical

The pool does not enforce a constant-product or any other invariant across swaps. executeFeeSwap and rebalanceSwap use flat fee percentages regardless of reserve ratios, meaning an attacker can push the reserve ratio arbitrarily far from equilibrium at the cost of the fee alone. After skewing reserves via repeated swaps, the attacker calls mint() with validatorToken; the weighted-denominator formula (N*reserveUserToken/SCALE + reserveValidatorToken) becomes heavily biased, minting far more or far fewer shares than fair value depending on which reserve was inflated. The attacker then burns to extract disproportionate reserves, net-extracting from honest LPs who cannot exit without loss.

K-invariant is not preserved: pool reserves can decrease without corresponding fee revenue when userToken is withdrawn via burn()Fee calculation asymmetry between executeFeeSwap (M=9970, 0.3% fee) and rebalanceSwap (N=9985, 0.15% fee adjustment) enables arbitrage extraction of protocol value and breaks fee symmetryBroken AMM invariant: mint() function fails to enforce equal-value deposits, allowing first minter to drain entire pool via donation attack
Zero-Burn Total-Supply Collapse Leading to Complete Pool Draincritical

An attacker exploits the zero-amount burn vulnerability (Finding 15) to systematically reduce totalSupply[poolId] to near-zero without withdrawing any reserves. Once totalSupply approaches zero, the attacker calls mint() with a small amountValidatorToken. With a near-zero totalSupply, the mint formula computes an astronomically large liquidity share for the attacker. The attacker then calls burn() with those shares, extracting essentially all remaining reserves. Combined with the inverted rebalanceSwap fee formula (Finding 6) that undercharges callers, the attacker can also pre-drain validator token reserves before executing the share collapse, maximizing the value stolen.

burn() function does not validate that calculated amountUserToken and amountValidatorToken are both non-zero, allowing zero-amount transfers and silent pool drains where LP tokens are burned without reducing reservesUnconditional +1 offset in rebalanceSwap() amountIn calculation causes systematic overpayment and breaks economic reciprocityDivision-before-multiplication rounding in _calculateBurnAmounts causes liquidity providers to receive systematically less than their fair share, draining LP value to contract over time
Donation Attack Amplified by Identical-Token Pool Corruptioncritical

An attacker first exploits the missing userToken != validatorToken check in executeFeeSwap (Finding 5/25) to create a same-token pool entry with an inflated reserveUserToken. They then call the one-sided mint() (Finding 1) with the validatorToken corresponding to the inflated userToken pool, triggering the weighted denominator formula that misprices liquidity shares because reserveUserToken is now corrupted. The attacker receives outsized liquidity shares relative to their deposit, then burns to extract both tokens from the pool, draining honest LPs.

Broken AMM invariant: mint() function fails to enforce equal-value deposits, allowing first minter to drain entire pool via donation attackNo validation that poolId tokens are distinct from each other; identical token addresses allowed, breaking pool invariantMissing input validation on token addresses in mint and burn functions allows pool to be created for identical tokens, violating intended behavior
Fee Asymmetry Arbitrage with Compounding Rounding Extractioncritical

The inverted rebalanceSwap formula (Finding 6) charges users less than fair value on every call. Combined with the executeFeeSwap fee direction mismatch (Finding 7) and the division rounding that systematically favors callers (Findings 4, 11, 12), a sophisticated attacker can construct a cyclic call sequence: executeFeeSwap followed by rebalanceSwap. Each cycle extracts a small net positive value due to the fee rate mismatch (0.3% vs 0.15%) and the inverted formula in rebalanceSwap. Repeated with flash-loan-scale capital, this drains pool reserves continuously without any capital at risk.

Fee calculation asymmetry between executeFeeSwap (M=9970, 0.3% fee) and rebalanceSwap (N=9985, 0.15% fee adjustment) enables arbitrage extraction of protocol value and breaks fee symmetryUnconditional +1 offset in rebalanceSwap() amountIn calculation causes systematic overpayment and breaks economic reciprocityexecuteFeeSwap uses incorrect rounding in (amountIn * M) / SCALE, always rounding down and leaking value to the protocol across cumulative callsFee calculation in executeFeeSwap() uses incorrect constant M (99.7%) instead of N (99.85%), causing protocol to lose fees on every swap
Unchecked ERC20 Return Value Enabling Reserve Divergence Followed by LP Drainhigh

The missing ERC20 return value check (Finding 16) allows a transfer-out to silently fail while reserve accounting proceeds as normal. If the validatorToken is a token that returns false on transfer (rather than reverting), executeFeeSwap decrements pool.reserveValidatorToken without the corresponding tokens actually leaving the contract. An attacker can pair this with the zero-burn vulnerability (Finding 15): after the reserve accounting is corrupted, burning LP shares against the now-incorrect reserve values allows the attacker to withdraw more tokens than their actual proportional share, draining honest LP funds.

Missing return value check on ERC20 transfer() calls allows silent failure, causing pool reserves to diverge from actual balancesburn() function does not validate that calculated amountUserToken and amountValidatorToken are both non-zero, allowing zero-amount transfers and silent pool drains where LP tokens are burned without reducing reserves

Agent Coverage

AgentStatusFindingsSeverityConfidenceDurationCoverage
reentrancysuccess25
85%3.8mCross-function reentrancy via external token transfers, K-invariant AMM formula correctness in mint and burn, Fee asymmetry between executeFeeSwap and rebalanceSwap, Rounding and precision loss in arithmetic operations, Input validation on token addresses, Unsafe down-casts from uint256 to uint128, Pool initialization with single token type, Donation attack patterns via liquidity seeding, Division before multiplication precision issues, Reciprocal swap formula consistency, Cross-function reentrancy via external calls, K-invariant violations in AMM formulas, Fee asymmetry and arbitrage opportunities, Unsafe downcasts and overflow/underflow, Rounding and precision loss in division-before-multiplication, Fee-on-transfer token handling, Return value checks on ERC20 transfers, Slippage protection and frontrunning vectors, Initial pool creation and donation attacks, Liquidity share calculation formulas, Division-before-multiplication precision loss in all arithmetic operations, Rounding direction in fee calculations (executeFeeSwap, rebalanceSwap), AMM K-invariant maintenance across swaps and liquidity operations, LP token mint/burn symmetry and share calculation, Pool reserve state consistency and bounds checking, Round-trip symmetry in reciprocal swap functions, Unsafe uint128 casts on user-controlled inputs, Missing userToken deposit in mint function, Rebalance swap offset asymmetry
access controlsuccess28
84%3.9mAccess control on all state-modifying functions (mint, burn, executeFeeSwap, rebalanceSwap), Reserve overflow/underflow in pool state updates, Fee asymmetry between executeFeeSwap (uses M) vs rebalanceSwap (uses N), Liquidity calculation in mint() for initial vs subsequent mints, Burn amount validation and zero-value transfers, Pool initialization logic and imbalanced reserve handling, Div-by-zero conditions in mint() when totalSupply is zero, Cast safety and bounds checking on uint128 operations, Access control and authorization (mint, burn, executeFeeSwap, rebalanceSwap), Liquidity pool initialization and invariant maintenance, Fee calculation and asymmetry between two swap paths, Rounding direction in division-before-multiplication patterns, Unsafe uint256 to uint128 downcasts and overflow checks, Reserve state corruption and pool balance tracking, Input validation on address parameters and amounts, Share accounting and LP withdrawal calculations, Mathematical consistency between related functions, Precision loss in repeated operations, Access control and authorization (all functions public/external, no onlyOwner guards), Rounding direction in all divisions (executeFeeSwap, rebalanceSwap, mint, _calculateBurnAmounts), Integer overflow/underflow via unsafe casts (uint128 casts in mint, burn, executeFeeSwap, rebalanceSwap), DEX invariant correctness (K-invariant assumptions, fee asymmetry between swap directions), LP token math (mint/burn parity, initial liquidity handling, MIN_LIQUIDITY cliff), Cross-function consistency (swap fees, reserve updates, total supply accounting), Reserve sufficiency checks (before and after transfers), Asymmetric pool initialization (zero-reserve cases), Division-before-multiplication precision loss across all arithmetic paths
economicsuccess27
82%3.9mFee swap path (executeFeeSwap) for fee asymmetry and rounding loss, Rebalance swap path (rebalanceSwap) for overflow and underflow conditions, Liquidity provision (mint) for proper reserve initialization and LP share calculation, Liquidity withdrawal (burn) for rounding loss in share redemption, Pool invariant maintenance across all state-mutating functions, Cross-function flow analysis for state consistency, Input validation and bounds checking (uint128 overflow protections), Token transfer order and reentrancy patterns, Asymmetric fee structure between executeFeeSwap and rebalanceSwap, Initial liquidity calculation and first-minter donation attack in mint(), Division-before-multiplication precision loss in mint() and burn(), Unsafe uint256 to uint128 downcasts and overflow checks, Missing K-invariant enforcement and pricing constraints, Fee-on-transfer token handling in executeFeeSwap(), Slippage protection and MEV exposure, Input validation on token addresses and parameters, Liquidity balance management in burn(), Hardcoded offsets and rounding asymmetries across functions, Rounding direction in swap and fee calculations (executeFeeSwap, rebalanceSwap), Precision loss in division operations (_calculateBurnAmounts, mint, burn), MEV and sandwich attack vectors (missing slippage protection, missing deadline), Fee-on-transfer token handling (balance delta verification), Integer overflow in arithmetic (Solidity 0.7.6 context), LP token inflation attacks (first-depositor attack, disproportionate contributions), Race conditions in burn and concurrent operations, Token transfer return value validation, Pool invariant maintenance across mint/burn/swap operations, Cross-function consistency in reserve accounting
logic validationsuccess28
77%4.1mInput validation on all external functions (mint, burn, executeFeeSwap, rebalanceSwap), Arithmetic safety: division-before-multiplication patterns, rounding direction, overflow in uint128 conversions, Pool state consistency: reserve updates vs. totalSupply, liquidity tracking, Fee calculation paths: executeFeeSwap vs rebalanceSwap formula asymmetry, ERC-20 integration: fee-on-transfer token handling, transfer ordering, Slippage protection and frontrunning vectors, Pool initialization and minimum liquidity logic, Arithmetic overflow/underflow in Solidity 0.7.6 (no built-in overflow protection) with uint256 multiplication in executeFeeSwap and rebalanceSwap, Unsafe downcasts from uint256 to uint128 in pool reserve updates, Precision loss from division-before-multiplication in mint(), _calculateBurnAmounts(), and rebalanceSwap(), Asymmetric fee structure between executeFeeSwap (M=9970) and rebalanceSwap (N=9985), Pool initialization asymmetry in mint() accepting only validatorToken, Zero-amount burn bypass allowing reserve ratio inflation without reserve removal, Rounding direction inconsistencies in swap and liquidity calculations, Pool state imbalance created by asymmetric initialization, Liquidity calculation weighting formula using fee constants instead of proportional reserves, Rounding direction in all division operations (executeFeeSwap, rebalanceSwap, mint, burn, _calculateBurnAmounts), LP token minting/burning mechanics and liquidity share calculation, AMM invariant enforcement (lack thereof in rebalanceSwap), Fee structure parity between executeFeeSwap (0.3%) and rebalanceSwap (0.15%), Pool reserve state transitions across all functions, Cross-function consistency: mint/burn, executeFeeSwap/rebalanceSwap round-trip behavior, MIN_LIQUIDITY burn application and asymmetry between first and subsequent deposits, Precision loss accumulation in repeated burns and swaps
code qualitysuccess27
86%4.7mERC-20 transfer/transferFrom return value handling, Fee calculation asymmetry between executeFeeSwap and rebalanceSwap, Liquidity minting formula and its weighting of token reserves, First-depositor pool initialization logic, Rounding direction in division operations (amountOut calculations), Unsafe uint256 to uint128 downcasts, Off-by-one errors in arithmetic (none found), Access control (none present, contract allows open liquidity operations), ERC-20 transfer/transferFrom compliance and return value handling, Fee calculation asymmetry between executeFeeSwap (M=9970) and rebalanceSwap (N=9985), Unsafe uint256 to uint128 downcasts in rebalanceSwap and executeFeeSwap, Division-before-multiplication precision loss in mint and burn, Initial pool liquidity calculation and inflation attack vectors, Rounding direction errors and favor asymmetry in swap pricing, Pool reserve state corruption via self-referential tokens, Liquidity share calculation formulas for fairness and MEV, Slippage protection and frontrunning vulnerability, Authorization checks on burn and mint operations, Accumulation of rounding errors across multiple transactions, ERC-20 transfer safety and return value handling, Unsafe downcasts from uint256 to uint128 without prior bounds checking, Rounding direction in division operations (burn amounts, rebalance fees), Fee asymmetry between executeFeeSwap and rebalanceSwap directional swaps, Fee-on-transfer token compatibility in pool reserve accounting, Liquidity mining and burn mechanics for share price calculations, AMM K-invariant preservation across swap operations, Sandwich attack vectors and slippage protection, Mint function first-depositor inflation defense (MIN_LIQUIDITY burn), Pool initialization and imbalanced reserve scenarios, Rounding errors in small-amount swaps (fee granularity), Cross-function consistency in reserve updates
compiler bugssuccess11
75%2.3mFee path asymmetry between swap functions (patterns #1 high), Rounding direction and division-before-multiplication (patterns #4, #6), Unsafe down-cast from uint256 to uint128 on user input (pattern #8), K-invariant and AMM pool arithmetic, Liquidity minting/burning and inflation attacks (patterns #9, #10), Cross-function reentrancy via IERC20 transfers, Input validation on all public functions, Pool initialization and liquidity minting in mint() function - found critical donation-attack flaw, Fee asymmetry between executeFeeSwap and rebalanceSwap - found critical fee-direction mismatch, Overflow and underflow in state mutations - verified most checks are correctly placed, no overflow bypass found, burn() function for LP withdrawal - found zero-amount transfer vulnerability, Input validation across all swap and LP functions - found missing userToken != validatorToken check in mint(), Rounding direction in swap calculations - found +1 overpayment in rebalanceSwap, Decimal conversion and scaling - contract assumes all tokens have same decimal handling (no cross-decimal math found), Reentrancy and CEI violations - contract uses transferFrom before state update in most cases, but executeFeeSwap has CEI issue, TWAP and oracle dependencies - no oracle calls found, only reserve-based AMM pricing, Rounding direction in mint() liquidity calculation (division-before-multiplication), Fee asymmetry between executeFeeSwap (M=9970) and rebalanceSwap (N=9985), Round-trip swap symmetry and arbitrage paths, LP token issuance and redemption parity, Precision loss from repeated integer division in _calculateBurnAmounts, Pool invariant maintenance (reserves consistency), Cross-function consistency in fee calculations
assembly safetysuccess15
78%4.6mInline assembly blocks and unsafe operations, Non-ASCII and homoglyph characters in identifiers and strings, Fee path asymmetry between executeFeeSwap and rebalanceSwap, AMM K-invariant and pricing constraints, Precision loss in division-before-multiplication arithmetic, Overflow and underflow in uint128 reserves, Pool initialization and liquidity calculations, Input validation on user-supplied addresses and amounts, Rounding direction in all arithmetic operations (mint, burn, executeFeeSwap, rebalanceSwap), Fee structure consistency across executeFeeSwap (M=9970) vs rebalanceSwap (N=9985) vs mint (N=9985) formulas, Division-before-multiplication precision loss in _calculateBurnAmounts, Unsafe down-casts to uint128 in executeFeeSwap and rebalanceSwap, Initial liquidity lock-up behavior in mint with MIN_LIQUIDITY, Consistency of fee rates between different swap functions, Input validation for zero-amount swaps, Cross-function invariants (round-trip symmetry, fee consistency), Pool invariant maintenance (reserve balance tracking), Liquidity provider share calculations for initial and subsequent deposits
l2 specificsuccess25
84%4.4mFee asymmetry between executeFeeSwap and rebalanceSwap swap directions, Division-before-multiplication rounding in mint, burn, and swap calculations, Integer overflow and unsafe uint128 downcasts in executeFeeSwap and rebalanceSwap, Liquidity share price precision across mint/burn lifecycle, Initial pool creation (mint) logic for dead-share handling, Reserve accounting and state transitions in all swap functions, Chainlink oracle and price feed usage (none present, N/A), Fee asymmetry between executeFeeSwap and rebalanceSwap - verified M vs N constants and pricing formulas, Initial pool initialization in mint() - identified missing userToken reserve setup and liquidity formula flaws, Division-before-multiplication rounding patterns - checked mint and burn calculation orders, Overflow and underflow in uint128 casts - examined _requireU128 checks and reserve updates, Burn amount validation - confirmed missing zero-amount checks in calculated transfers, rebalanceSwap +1 offset - verified hardcoded rounding implementation, Pool reserve manipulation via zero-value transfers - traced burn path with zero amounts, Two-token AMM invariant enforcement - checked if K-invariant or pricing constraints exist, Cross-function state consistency - verified reserve updates across executeFeeSwap, rebalanceSwap, mint, burn, Input validation completeness - reviewed all require statements and missing validations, Rounding direction in division operations (burn, mint, swap), Unsafe uint128 casts and overflow checks in pool reserve updates, Cross-function consistency between swap fee rates and pricing models, AMM invariant correctness (K-invariant, weighted invariants), Precision loss in accumulated arithmetic (division before multiplication), Input validation for token address distinctness across all swap functions, Liquidity check boundary conditions and MEV vectors, Edge cases in LP token calculations (zero-amount burns, rounding-to-zero scenarios), First-LP mint behavior and MIN_LIQUIDITY handling
math verificationsuccess17
72%4.4mmint() initial liquidity calculation with division-before-subtraction precision loss, mint() non-initial liquidity calculation asymmetric formula, mint() one-sided liquidity provision vulnerability, executeFeeSwap() fee calculation and rounding direction, rebalanceSwap() amountIn calculation and overflow checks, burn() share verification and proportional redemption, Liquidity balance tracking and totalSupply invariant, Pool reserve management across all functions, Cross-function consistency (mint-burn-swap state transitions), Fee calculation asymmetry between executeFeeSwap (M=9970) and rebalanceSwap (N=9985), mint() function initial liquidity calculation and single-token deposit vulnerability, burn() function rounding direction and precision loss in withdraw calculations, rebalanceSwap() amountIn calculation and +1 offset correctness, Unsafe uint128 down-cast patterns and overflow checks, Cross-function state consistency between mint and burn, Pool K-invariant enforcement and economic incentives, Liquidity calculation precision loss in mint(), Rounding direction in burn() / _calculateBurnAmounts() - systematic under-payout to LPs, Fee asymmetry between executeFeeSwap (M=9970) and rebalanceSwap (N=9985) - round-trip imbalance, Arbitrary recipient in rebalanceSwap() - forced fund transfer vulnerability, Pool initialization via MIN_LIQUIDITY dead shares - intentional design, Pool existence checks in burn() - implicit guard via liquidityBalance, Division-before-multiplication in entire contract, Cross-function consistency between mint/burn/swap operations, Unsafe down-cast validation via _requireU128(), Overflow checks in pool reserve updates

Failed Agents

assembly safetyFailed

Zod validation failed: findings.3.affectedFile: Invalid input: expected string, received null; findings.3.affectedLines: Invalid input: expected string, received null; findings.3.codeSnippet: Invalid input: expected string, received null; findings.3.impact: Invalid input: expected string, received null; findings.3.remediation: Invalid input: expected string, received null; findings.6.affectedFile: Invalid input: expected string, received null; findings.6.affectedLines: Invalid input: expected string, received null; findings.6.codeSnippet: Invalid input: expected string, received null; findings.6.impact: Invalid input: expected string, received null; findings.6.remediation: Invalid input: expected string, received null; findings.8.affectedFile: Invalid input: expected string, received null; findings.8.affectedLines: Invalid input: expected string, received null; findings.8.codeSnippet: Invalid input: expected string, received null; findings.8.impact: Invalid input: expected string, received null; findings.8.remediation: Invalid input: expected string, received null

How this affects your report: findings normally surfaced by this specialist are missing; overlapping coverage from other agents still applies.

Scope and Methodology

Target0x2a26886847ec46a0e677d75ee4aab1b9550511f9
ChainEthereum
Complexitymoderate
Standards DetectedERC20
Analysis Modelhaiku + Claude Sonnet 4.6
Specialist Agents28
Agent Types
reentrancyaccess controleconomiclogic validationcode qualitycompiler bugsassembly safetyl2 specificmath verification
Scope TemplateGeneral Smart Contract (auto-selected)
MethodologyAutomated multi-agent analysis. Each specialist agent independently reviews the contract source code for vulnerabilities in its domain. Findings are deduplicated, scored, and synthesized into this report.
Findings are gated by demonstrated exploit feasibility against the analyzed contract. Observations that describe accepted blockchain behavior, consensus-layer issues, or infeasible preconditions are excluded from scored findings. See scope policy.

Severity Classification

CriticalDirect loss of funds or complete protocol compromise. Exploitable with high likelihood. Requires immediate remediation.
HighSignificant risk to funds or protocol integrity. Conditionally exploitable or requires specific circumstances. Should be fixed before deployment.
MediumLimited or conditional impact. May require unlikely conditions to exploit. Should be addressed but not blocking.
LowMinor impact. Best practice deviations, minor inefficiencies. Fix when convenient.
InformationalNo direct security impact. Code quality observations, gas optimizations, style recommendations.

Limitations

This automated audit has inherent limitations. The following areas are not covered.

Disclaimer

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.

Embed Badge
WalletGuard Audit Badge
Markdown
[![WalletGuard Audit](https://walletguard.ai/api/badge/16ae9122-dd85-42ae-9c23-679c1ee0df1c)](https://walletguard.ai/audit/16ae9122-dd85-42ae-9c23-679c1ee0df1c)
HTML
<a href="https://walletguard.ai/audit/16ae9122-dd85-42ae-9c23-679c1ee0df1c">
  <img src="https://walletguard.ai/api/badge/16ae9122-dd85-42ae-9c23-679c1ee0df1c" alt="WalletGuard Audit Badge" />
</a>
WalletGuardSecured by WalletGuard
How We AuditView all reports for this contractThis report was produced by generic vulnerability pattern matching.
Modelhaiku+sonnet
Duration14.7m
CostN/A
Tokens- in / - out
Source verified via Etherscan