
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.
src/SizeStorage.solLines: 108-131src/libraries/DepositTokenLibrary.solFunction: depositUnderlyingCollateralTokenLines: 23-27src/libraries/AccountingLibrary.solFunction: debtTokenAmountToCollateralTokenAmountLines: 33-40| Agent | Status | Findings | Severity | Confidence | Duration | Coverage |
|---|---|---|---|---|---|---|
| reentrancy | success | 23 | 2H3M | 76% | 7.4m | Cross-function reentrancy in Liquidate, Repay, Claim, Compensate, SelfLiquidate, CEI ordering in all execute* functions, ERC-777/ERC-1155 callback patterns (not applicable - uses standard ERC20), Multicall payable ETH handling and balance manipulation, Chainlink oracle staleness checks in PriceFeed, Access control on NonTransferrableToken transferFrom, Arbitrary from address in DepositTokenLibrary, UpdateConfig validation logic for crLiquidation, SellCreditMarket maxCashAmountOut formula correctness, UUPS upgrade authorization, Flash loan callback patterns (not present), ERC-4626 inflation attack patterns (not applicable - not ERC-4626), Integer overflow/underflow (Solidity 0.8.23 with built-in checks), Sequencer uptime feed check in PriceFeed, borrowATokenCap bypass via multicall, Cross-function reentrancy via NonTransferrableScaledToken.transferFrom (confirmed no hooks due to onlyOwner), executeLiquidateWithReplacement debt token double-minting chain analysis, Compensate.executeCompensate fragmentation fee bypass via zero collateral, Multicall.multicall borrowAToken cap bypass via balanceOf vs totalSupply inconsistency, SellCreditMarket RESERVED_ID lender event logging bug, PriceFeed sequencer grace period logic (confirmed correct, not inverted), Math.binarySearch underflow/infinite loop analysis, Claim.executeClaim storage reference ordering after reduceCredit, NonTransferrableToken.transferFrom onlyOwner enforcement (no reentrancy callbacks), Deposit.executeDeposit address(this).balance vs msg.value (already found by prior agents), UpdateConfig crLiquidation/crOpening invariant (already found by prior agents), Chainlink answeredInRound check (already found by prior agents), Cross-function reentrancy in Liquidate, Repay, Claim, Compensate, LiquidateWithReplacement double-debt and liquidityIndexAtRepayment=0 causing division by zero in Claim, Multicall ETH locking and balance theft, validateVariablePoolHasEnoughLiquidity post-execution ordering, NonTransferrableScaledToken rounding in transferFrom, Multicall borrowAToken cap bypass using balanceOf vs totalSupply, PriceFeed sequencer uptime check logic (confirmed inverted grace period - already found), UpdateConfig crLiquidation/crOpening invariant (already found, extensively covered), SellCreditMarket debt position lender field (already found, informational), Compensate exiterCreditRemaining stale memory (analyzed in detail), BuyCreditMarket exactAmountIn RESERVED_ID path, Math.binarySearch uint256 underflow (already found), getCreditAmountIn fee formula (already found), Chainlink answeredInRound check (already found) |
| access control | success | 16 | 4H3M1L | 82% | 6.2m | Access control on all state-modifying functions (deposit, withdraw, repay, claim, liquidate, etc.), Role-based access control for admin functions (updateConfig, pause, unpause, setVariablePoolBorrowRate, liquidateWithReplacement), UUPS upgrade authorization via _authorizeUpgrade, Initializer protection via _disableInitializers() in constructor and initializer modifier, Multicall delegatecall safety and msg.value reuse across calls, Chainlink oracle staleness checks in PriceFeed._getPrice, Sequencer uptime feed check in PriceFeed.getPrice, Signature replay - not applicable, no EIP-712 signatures used, Token transfer patterns (NonTransferrableToken onlyOwner guards), Reentrancy across liquidate, selfLiquidate, repay, claim flows, LiquidateWithReplacement debt restoration logic and lender claim impact, ETH deposit using address(this).balance vs msg.value, getCreditAmountIn/getCashAmountOut formula consistency, Credit/debt position ID range checks to prevent confusion between debt and credit position types, UpdateConfig validation including post-update invariant checks, Borrower CR validation after sellCreditMarket and withdraw, Cap validation for borrowAToken supply, Cross-function reentrancy via multicall and state.data.isMulticall flag, LiquidateWithReplacement chained effects on Claim.executeClaim (division by zero), validateVariablePoolHasEnoughLiquidity amount parameter correctness in liquidateWithReplacement, Compensate fragmentation fee bypass via zero collateral balance, getCashAmountOut fee symmetry vs getCashAmountIn, ETH locking in multicall with no withdrawal mechanism, UpdateConfig crLiquidation progressive reduction attack path, Claim.executeClaim liquidityIndexAtRepayment zero check, YieldCurveLibrary.getAPR binarySearch return value handling, Cross-function reentrancy paths through borrowAToken.transferFrom, NonTransferrableScaledToken dust accumulation impact, Deduplication against all prior findings |
| economic | success | 23 | 3H1M2L | 77% | 7.0m | Chainlink oracle staleness checks in PriceFeed.sol (answer > 0, updatedAt, answeredInRound >= roundId, sequencer uptime feed), Flash loan attack vectors via multicall and balance-dependent pricing, ERC-4626 vault inflation attack patterns (not applicable - no ERC-4626 vault present), Liquidation logic in Liquidate.sol and LiquidateWithReplacement.sol, Fee calculation correctness across getCashAmountOut, getCreditAmountIn, getCashAmountIn, getCreditAmountOut, SellCreditMarket and BuyCreditMarket execution flows and credit position creation, Multicall reentrancy and ETH handling, UpdateConfig parameter validation and invariant enforcement, Compensate fragmentation fee enforcement, Oracle price manipulation resistance (single Chainlink feed with staleness), Access control on sensitive functions (liquidateWithReplacement KEEPER_ROLE, updateConfig DEFAULT_ADMIN_ROLE), UUPS upgrade authorization (_authorizeUpgrade restriction to DEFAULT_ADMIN_ROLE), Interest rate model and variable pool borrow rate staleness, Collateral ratio calculations and liquidation threshold checks, NonTransferrableScaledToken liquidity index scaling correctness, Deposit/Withdraw token flow and Aave V3 integration, CapsLibrary borrow aToken cap enforcement in multicall vs single call, Governance attack vectors (no governance token present), Sandwich/MEV exposure on liquidations and credit market operations, LiquidateWithReplacement full execution flow and debt token accounting, Compensate RESERVED_ID path and fragmentation fee bypass, CapsLibrary borrowAToken balance vs totalSupply in multicall cap check, SellCreditMarket event log corruption for debt position lender, Claim executeClaim CEI pattern and storage reference safety, PriceFeed sequencer uptime check logic re-verification, getCreditAmountIn fee formula consistency analysis, Chaining of prior findings for compound exploits, Blind spots in previously unflagged code paths, validateBorrowATokenIncreaseLteDebtTokenDecrease tracking scope, LiquidateWithReplacement full execution flow including debt token double-minting and liquidityIndexAtRepayment reset, Claim.executeClaim division-by-zero when liquidityIndexAtRepayment=0 after LiquidateWithReplacement, buyCreditMarket and sellCreditMarket post-execution liquidity validation ordering, BuyCreditMarket RESERVED_ID exactAmountIn path always taking no-fractionalization branch, Compensate RESERVED_ID path exiterCreditRemaining calculation with stale in-memory credit, multicall ETH locking and address(this).balance race condition, NonTransferrableScaledToken.transferFrom rounding direction and cumulative dust loss, getCreditPositionProRataAssignedCollateral returning 0 in multicall SelfLiquidate race, PriceFeed sequencer uptime check logic (inverted grace period - already found), PriceFeed missing answeredInRound check (already found), UpdateConfig crLiquidation/crOpening invariant violations (already found extensively), Math.binarySearch infinite loop (already found), SellCreditMarket lender=msg.sender debt position creation (already found), Multicall ETH reuse via address(this).balance (already found), getCreditAmountIn fee formula mismatch (already found), Flash loan attack surface - no token balance dependencies for pricing found, Oracle manipulation via flash loans - not applicable since price is from Chainlink, Governance/role capture - KEEPER_ROLE required for liquidateWithReplacement is appropriate, Reentrancy paths through external calls in executeLiquidate (already found) |
| logic validation | success | 27 | 3H2M2L | 75% | 7.6m | Chainlink oracle staleness checks in PriceFeed.sol - missing answeredInRound check, Arithmetic safety in AccountingLibrary - fee calculations, division/multiplication order, State machine integrity - liquidation, repayment, claim flows, Multicall ETH double-spend vulnerability - msg.value vs address(this).balance, LiquidateWithReplacement accounting - double minting analysis, UpdateConfig parameter validation correctness - crLiquidation direction bug, Compensate logic - amountToCompensate calculation with RESERVED_ID, SellCreditMarket/BuyCreditMarket credit position creation flows, binarySearch underflow edge cases, NonTransferrableScaledToken - scaling calculations, DepositTokenLibrary - Aave integration, scaledBalance tracking, CapsLibrary - borrow aToken cap validation logic, RiskLibrary - collateral ratio calculations, YieldCurveLibrary - APR interpolation, stale rate checks, Access control on all admin functions, UUPS upgrade authorization, Sequencer uptime feed validation in PriceFeed, Self-liquidation validation - collateral ratio checks, Claim flow - liquidity index calculation at repayment, Compensate.executeCompensate RESERVED_ID branch fragmentation fee bypass, Math.binarySearch uint256 underflow analysis with exact boundary conditions, SellCreditMarket lender assignment two-step flow and event emission, Multicall borrowAToken cap check using balanceOf vs totalSupply discrepancy, NonTransferrableScaledToken.transferFrom rounding direction and dust accumulation, Chain exploit: UpdateConfig crLiquidation reduction + multicall cap bypass, getCreditPositionProRataAssignedCollateral with stale memory creditPosition in multicall context, Claim.executeClaim access control and who receives funds, Repay.executeRepay reentrancy analysis (onlyOwner restriction on transferFrom), YieldCurveLibrary.getAdjustedAPR stale rate interval zero bypass, Cross-function state consistency between compensate and selfLiquidate in multicall, LiquidateWithReplacement full flow: executeLiquidate then state restoration, liquidityIndexAtRepayment reset to 0, debt token double-mint, Claim.executeClaim: division by liquidityIndexAtRepayment=0 after LiquidateWithReplacement, validateVariablePoolHasEnoughLiquidity in liquidateWithReplacement: checks issuanceValue not futureValue, BuyCreditMarket.executeBuyCreditMarket: exactAmountIn=true RESERVED_ID path forces no-fractionalization, Compensate.executeCompensate: memory vs storage reads, exiterCreditRemaining calculation, fragmentation fee cap, NonTransferrableScaledToken.transferFrom: rounding direction in scaledAmount, UpdateConfig cross-parameter validation for crOpening and crLiquidation, Multicall ETH locking: payable multicall with no ETH rescue mechanism, SellCreditMarket event emission: wrong dueDate argument, Tenor boundary manipulation via block.timestamp, Math.binarySearch infinite loop on single-element arrays (already found), Chainlink oracle checks: answeredInRound, updatedAt (already found), PriceFeed sequencer grace period logic (already found) |
| code quality | success | 16 | 81% | 9.5m | ERC-20 compliance for NonTransferrableToken and NonTransferrableScaledToken, Chainlink oracle staleness checks in PriceFeed, Liquidation logic in Liquidate and LiquidateWithReplacement, Reentrancy paths through external calls (borrowAToken.transferFrom, collateralToken.transferFrom), Cap enforcement logic in CapsLibrary and Multicall, UpdateConfig parameter validation and invariant preservation, Deposit ETH handling and address(this).balance usage, Fee calculation arithmetic in AccountingLibrary (getCashAmountOut, getCreditAmountIn, getCashAmountIn, getCreditAmountOut), SellCreditMarket and BuyCreditMarket execution flows, Compensate execution including fragmentation fee logic, Claim execution and liquidity index math, Access control: DEFAULT_ADMIN_ROLE, KEEPER_ROLE, BORROW_RATE_UPDATER_ROLE, PAUSER_ROLE, UUPS upgrade safety (_authorizeUpgrade restriction), Multicall delegatecall pattern and cap validation, YieldCurve validation and getAPR interpolation, LoanLibrary position ID range checks, RiskLibrary collateral ratio calculations, Sequencer uptime feed check in PriceFeed, Storage layout in SizeStorage, ERC-1967 proxy implementation slot, LiquidateWithReplacement flow: liquidityIndexAtRepayment zeroing and claim interaction, validateVariablePoolHasEnoughLiquidity amount parameter correctness in liquidateWithReplacement, Compensate fragmentation fee cap-by-balance exploit path, UpdateConfig crLiquidation one-way ratchet limitation, Math.binarySearch uint256 underflow in high=mid-1 path, NonTransferrableScaledToken.transferFrom precision loss, SellCreditMarket event incorrect dueDate field, NonTransferrableToken ERC-20 compliance for allowance, Chaining of prior findings for amplified impact, Claim.executeClaim division by zero when liquidityIndexAtRepayment==0, BuyCreditMarket/SellCreditMarket exactAmountIn path fee formula consistency, Multicall ETH balance exploit amplification analysis, getCreditAmountIn fee formula for both cases | |
| compiler bugs | success | 13 | 1M | 82% | 4.2m | Chainlink oracle integration - latestRoundData checks (answer > 0, updatedAt freshness, answeredInRound >= roundId), Sequencer uptime feed grace period logic, Liquidation collateral calculations and fee splits, SellCreditMarket/BuyCreditMarket credit amount calculations and fee formulas, Compensate flow with RESERVED_ID - fragmentation fee avoidance, UpdateConfig invariant validation ordering, Multicall reentrancy and msg.value reuse patterns, Access control on liquidateWithReplacement (KEEPER_ROLE), UUPS upgrade authorization (DEFAULT_ADMIN_ROLE), NonTransferrableScaledToken transferFrom - scaled amount arithmetic, Deposit ETH flow via msg.value and WETH wrapping, CapsLibrary borrowAToken cap enforcement, YieldCurve binary search bounds, LiquidateWithReplacement double debt token mint pattern, Claim accrued interest calculation using liquidityIndex, Compiler bug patterns for solc 0.8.23 (no known matching bugs in this version range), LiquidateWithReplacement full execution flow including debt token lifecycle, Compensate RESERVED_ID path fragmentation fee bypass, UpdateConfig crLiquidation one-directional ratchet preventing increases, SellCreditMarket RESERVED_ID lender assignment in CreateDebtPosition event, Claim.executeClaim division-by-zero when liquidityIndexAtRepayment=0, Cross-function chains between LiquidateWithReplacement and Claim, PriceFeed sequencer uptime check logic (covered by prior findings), Chainlink answeredInRound check (covered by prior findings), Multicall ETH balance reuse (covered by prior findings), Reentrancy in executeLiquidate (covered by prior findings), Compiler bug analysis: pragma 0.8.23 is outside all affected compiler bug ranges, Claim.executeClaim division by liquidityIndexAtRepayment=0 after LiquidateWithReplacement reset, validateVariablePoolHasEnoughLiquidity called with issuanceValue vs futureValue in liquidateWithReplacement, Compensate.executeCompensate fragmentation fee bypass when borrower has zero collateral, Math.binarySearch uint256 underflow when mid==0 and array[mid] > value, NonTransferrableScaledToken.transferFrom round-down precision loss chaining with protocol accounting, Cross-function chains: LiquidateWithReplacement -> Claim division-by-zero chain, Cross-function chains: UpdateConfig crLiquidation -> multicall cap bypass chain from prior findings, SellCreditMarket lender assignment correctness (covered by prior findings), Compensate exiterCreditRemaining stale memory issue (covered by prior findings), PriceFeed staleness and sequencer uptime checks (covered by prior findings), ETH multicall msg.value reuse (covered by prior findings) |
| assembly safety | success | 22 | 1H | 81% | 7.4m | Full codepoint scan for non-ASCII characters (RTLO U+202E, zero-width joiners U+200D/U+200B/U+200C, Cyrillic homoglyphs) in all identifiers, comments, and strings — none found, Inline assembly{} blocks — none present in any file, Chainlink oracle staleness checks in PriceFeed.sol — missing answeredInRound >= roundId check, Sequencer uptime feed validation completeness, UpdateConfig parameter validation logic (crLiquidation guard is backwards vs crOpening), Deposit.executeDeposit ETH handling with address(this).balance in multicall context, executeLiquidateWithReplacement debt token accounting — old borrower burn + new borrower mint, Claim.executeClaim CEI ordering and reentrancy surface, Compensate.executeCompensate double-reduction analysis, SellCreditMarket maxCashAmountOut formula correctness, NonTransferrableToken and NonTransferrableScaledToken transferFrom access control, Multicall delegatecall safety and isMulticall flag, UUPS upgrade authorization via _authorizeUpgrade, CapsLibrary borrow cap enforcement, RiskLibrary collateral ratio calculations, AccountingLibrary getCashAmountOut/getCreditAmountIn/getCreditAmountOut/getCashAmountIn formula consistency, LoanLibrary position ID range checks, YieldCurveLibrary interpolation and STALE_RATE checks, Full codepoint scan for non-ASCII characters (RTLO U+202E, zero-width joiners U+200D/200B/200C, Cyrillic homoglyphs) — none found, Assembly blocks — none present in any source file, LiquidateWithReplacement double-debt accounting chain analysis — confirmed net effect is correct, Multicall borrowAToken supply measurement (balanceOf vs totalSupply) in cap validation, Compensate RESERVED_ID branch fragmentation fee bypass analysis, SellCreditMarket event data integrity for CreateDebtPosition with wrong lender, YieldCurveLibrary stale rate interval = 0 behavior and its effect on marketRateMultiplier offers, Math.binarySearch edge cases with empty arrays and uint256 underflow, PriceFeed sequencer uptime check logic (already covered by prior findings), UpdateConfig crLiquidation/crOpening invariant (already covered by prior findings), Deposit.executeDeposit address(this).balance ETH reuse (already covered by prior findings), Chainlink answeredInRound check (already covered by prior findings), Cross-function reentrancy paths through NonTransferrableScaledToken.transferFrom, Claim.executeClaim access control — anyone can trigger but funds go to creditPosition.lender, Repay.executeRepay access control — anyone can repay but msg.sender pays, no fund risk, validateBorrowATokenIncreaseLteDebtTokenDecrease measurement inconsistency analysis, LiquidateWithReplacement.executeLiquidateWithReplacement: full execution flow including liquidityIndexAtRepayment reset and debt token mint/burn accounting, Claim.executeClaim: division by liquidityIndexAtRepayment and impact of zero reset from LiquidateWithReplacement, Size.liquidateWithReplacement: return value handling and liquidity validation against issuanceValue vs futureValue, Compensate.executeCompensate: RESERVED_ID path and exiterCreditRemaining calculation with stale in-memory values, Math.binarySearch: uint256 underflow analysis for all reachable call paths from YieldCurveLibrary, Size.multicall: ETH locking when not consumed by deposit, no recovery mechanism, AccountingLibrary.getCashAmountOut vs getCreditAmountIn: fee base asymmetry between exactAmountIn and exactAmountOut paths, YieldCurveLibrary.getAdjustedAPR: variablePoolBorrowRateStaleRateInterval=0 behavior with non-zero marketRateMultiplier, PriceFeed.getPrice and _getPrice: sequencer check logic and Chainlink round validity, UpdateConfig.executeUpdateConfig: crOpening/crLiquidation invariant enforcement, NonTransferrableScaledToken: transferFrom rounding and owner-only access patterns, Multicall ETH balance reuse attack surface, SellCreditMarket.executeSellCreditMarket: lender assignment in createDebtAndCreditPositions vs createCreditPosition, CapsLibrary: balanceOf vs totalSupply distinction in cap validation, Complete codepoint scan for non-ASCII characters: none found, Inline assembly blocks: none present in any contract file |
| l2 specific | success | 27 | 1H2M1L | 80% | 8.1m | Chainlink oracle staleness checks (answeredInRound, updatedAt, price > 0), Sequencer uptime feed validation in PriceFeed.getPrice(), Cross-function reentrancy in liquidate/liquidateWithReplacement/claim flows, Multicall ETH deposit using address(this).balance vs msg.value, Borrow cap enforcement during multicall (CapsLibrary), Credit/debt accounting invariants in compensate, sellCreditMarket, buyCreditMarket, UpdateConfig parameter validation for crOpening/crLiquidation invariants, YieldCurve stale rate interval bypass, SellCreditMarket maxCashAmountOut formula correctness, LiquidateWithReplacement debt token accounting, ERC1967 UUPS upgrade authorization (DEFAULT_ADMIN_ROLE), NonTransferrableScaledToken transferFrom scaling arithmetic, Collateral ratio calculation precision, Block.timestamp manipulation risks in tenor calculations, Access control on liquidateWithReplacement (KEEPER_ROLE gated), ETH handling and WETH wrapping in deposit flow, validateBorrowATokenCap vs validateBorrowATokenIncreaseLteDebtTokenDecrease consistency, Math.binarySearch underflow analysis - determined to be safe for valid inputs, NonTransferrableScaledToken.transferFrom rounding direction and compounding effects, Compensate.executeCompensate fragmentation fee bypass via zero collateral balance, UpdateConfig crLiquidation wrong comparison direction preventing legitimate admin increases, ETH stuck in contract via selfdestruct combined with address(this).balance in deposit, LiquidateWithReplacement debt accounting - verified as correct by full flow trace, SellCreditMarket lender placeholder pattern - verified as intentional design, Claim.executeClaim double-rounding analysis, PriceFeed sequencer uptime feed additional validation gaps, buyCreditMarket post-hoc liquidity check safety, Compensate stale memory copy analysis - verified as not a bug, Cross-function reentrancy chains across liquidate/repay/claim, getCreditAmountIn fee formula consistency check, LiquidateWithReplacement full execution flow including liquidityIndexAtRepayment=0 reset impact on Claim, Size.liquidateWithReplacement return value used for liquidity validation (issuanceValue vs futureValue), Compensate fragmentation fee cap at user balance allowing free fractionalization, Multicall ETH locking — no withdraw mechanism for accidentally sent ETH, SellCreditMarket lender event inconsistency from two-step position creation, getCreditAmountIn fee formula correctness for fractional credit path, Cross-function exploit chains between prior findings, Claim.executeClaim division-by-zero risk from liquidityIndexAtRepayment=0, All paths in BuyCreditMarket, SellCreditMarket, Liquidate, LiquidateWithReplacement, Compensate, Repay, Claim, PriceFeed sequencer uptime logic (confirmed inverted grace period in prior findings), UpdateConfig crOpening/crLiquidation invariant (confirmed broken in prior findings), Math.binarySearch infinite loop (confirmed in prior findings), NonTransferrableScaledToken.transferFrom rounding (confirmed in prior findings), Deposit.executeDeposit ETH balance reuse in multicall (confirmed in prior findings) |
| math verification | success | 25 | 2H2M | 81% | 7.0m | All fee calculation formulas in AccountingLibrary (getCashAmountOut, getCreditAmountIn, getCreditAmountOut, getCashAmountIn), Algebraic consistency between exactAmountIn and exactAmountOut paths in BuyCreditMarket and SellCreditMarket, Chainlink oracle staleness checks in PriceFeed._getPrice(), Sequencer uptime feed grace period logic, Liquidation profit formulas in Liquidate.executeLiquidate(), LiquidateWithReplacement issuanceValue and profit calculations, UpdateConfig parameter validation logic and invariant preservation, Compensate fragmentation fee bypass via zero collateral, Claim accrued interest calculation (mulDivDown on liquidity index ratio), Collateral ratio calculations in RiskLibrary, debtTokenAmountToCollateralTokenAmount rounding direction, getSwapFeePercent rounding direction impact on downstream calculations, NonTransferrableScaledToken transferFrom scaling (divide before scale vs scale before transfer), Multicall borrowAToken cap validation bypass, SelfLiquidate pro-rata collateral assignment, YieldCurveLibrary interpolation arithmetic, Event emission correctness in SellCreditMarket, AccountingLibrary fee formulas: getCashAmountOut, getCreditAmountIn, getCreditAmountOut, getCashAmountIn — algebraic consistency between inverse paths, LiquidateWithReplacement debtToken accounting: double-mint analysis, futureValue reset, liquidityIndexAtRepayment=0 reset impact on Claim, Claim.executeClaim division by liquidityIndexAtRepayment — reachability of zero-denominator, NonTransferrableScaledToken.transferFrom rounding direction and per-transfer loss, Compensate fragmentation fee enforcement — capped by collateral balance allowing fee-free compensation, BuyCreditMarket RESERVED_ID path — maxCashAmountIn == cashAmountIn intentionality, SellCreditMarket tenor calculation block.timestamp staleness, PriceFeed oracle staleness checks (covered in prior findings — not re-reported), UpdateConfig invariant enforcement (covered in prior findings — not re-reported), Multicall ETH reuse via address(this).balance (covered in prior findings — not re-reported), getSwapFeePercent double rounding-up impact, validateBorrowATokenIncreaseLteDebtTokenDecrease correctness, YieldCurveLibrary linear interpolation precision, binarySearch edge cases at array boundaries, All arithmetic formulas in AccountingLibrary: getCashAmountOut, getCashAmountIn, getCreditAmountOut, getCreditAmountIn, getSwapFeePercent, LiquidateWithReplacement chained exploit: futureValue reset + liquidityIndexAtRepayment reset + debt token double-mint, Claim.executeClaim division by zero when liquidityIndexAtRepayment=0 after LiquidateWithReplacement, validateVariablePoolHasEnoughLiquidity in liquidateWithReplacement - checks issuanceValue vs futureValue, NonTransferrableScaledToken.transferFrom rounding behavior and dust accumulation, Compensate fragmentation fee bypass via zero collateral balance, BuyCreditMarket exactAmountIn=true with RESERVED_ID always takes no-fractionalization path, SellCreditMarket maxCashAmountOut formula consistency with getCashAmountOut, Cross-function reentrancy paths through borrowAToken.transferFrom, PriceFeed oracle checks - confirming grace period inversion (already found), Math.binarySearch uint256 underflow (already found), UpdateConfig crLiquidation/crOpening invariant violations (already found), Multicall ETH balance reuse (already found), UUPS proxy upgrade safety, Deposit/Withdraw token flow and cap enforcement |
| upgrade | success | 23 | 1H4M1L | 83% | 6.4m | UUPS proxy pattern - constructor calls _disableInitializers(), initialize() has initializer modifier, Storage layout in SizeStorage - single State struct, no __gap array, Chainlink oracle checks in PriceFeed._getPrice - missing answeredInRound check, Sequencer uptime feed logic in PriceFeed.getPrice, Multicall ETH handling in Deposit.executeDeposit, UpdateConfig parameter validation logic, Liquidation profit calculation in Liquidate.executeLiquidate, Claim interest accrual calculation via liquidityIndex, BuyCreditMarket and SellCreditMarket fee calculations, Compensate flow - RESERVED_ID path creates new debt, NonTransferrableScaledToken scaled balance accounting, DepositTokenLibrary - aToken scaledBalance tracking, Access control roles for all admin functions, Reentrancy risks in state changes before external calls, Flash loan / multicall ETH reuse vulnerability, YieldCurveLibrary interpolation and APR calculation, Math.binarySearch for yield curve lookup, CapsLibrary borrow token cap enforcement, LiquidateWithReplacement debt double-counting and state sequencing, Compensate RESERVED_ID path: new debt creation, amountToCompensate calculation, fragmentation fee bypass, Math.binarySearch edge cases: empty array, underflow in uint256 arithmetic, NonTransferrableToken/NonTransferrableScaledToken owner privilege escalation via UUPS upgrade, Claim.executeClaim CEI order and Aave dependency for liquidityIndex(), getSwapFeePercent rounding with mulDivUp at extreme tenor/APR values, SellCreditMarket intermediate state with wrong lender between createDebtAndCreditPositions and createCreditPosition, UpdateConfig crLiquidation/crOpening invariant — already extensively covered, PriceFeed sequencer check and answeredInRound — already covered, Multicall ETH balance reuse — already covered, Cross-function reentrancy through NonTransferrableToken (determined not possible as onlyOwner prevents external re-entry), YieldCurveLibrary.getAdjustedAPR stale rate bypass when interval=0, validateBorrowATokenIncreaseLteDebtTokenDecrease uses balance not totalSupply, CapsLibrary validateBorrowATokenCap bypassed during multicall, Chainlink oracle missing answeredInRound check — already covered, Access control on liquidateWithReplacement (KEEPER_ROLE) — reviewed, UUPS _disableInitializers in constructor — correctly present, Storage layout in SizeStorage for upgrade safety, LiquidateWithReplacement.executeLiquidateWithReplacement full flow including liquidityIndexAtRepayment reset and its impact on Claim.executeClaim, Claim.executeClaim division by liquidityIndexAtRepayment=0 for replaced loans, validateVariablePoolHasEnoughLiquidity in liquidateWithReplacement checking issuanceValue vs futureValue, BuyCreditMarket.executeBuyCreditMarket exactAmountIn=true with RESERVED_ID - maxCredit rounding direction, Compensate.executeCompensate RESERVED_ID path - exiterCreditRemaining always zero bug, Size.multicall payable ETH locking when no deposit call is made, NonTransferrableScaledToken.transferFrom mulDivDown precision loss, YieldCurveLibrary.getAdjustedAPR stale rate interval zero behavior, PriceFeed sequencer uptime check grace period inversion (confirmed in prior findings), UpdateConfig crLiquidation/crOpening invariant violations (confirmed in prior findings), Math.binarySearch uint256 underflow (confirmed in prior findings), Multicall ETH address(this).balance reuse (confirmed in prior findings), SellCreditMarket lender assignment in createDebtAndCreditPositions (confirmed in prior findings), Chaining of UpdateConfig bug with liquidation to drain protocol, Access control on all admin functions, UUPS proxy initialization - disableInitializers present in constructor, Storage layout collision risks in upgrade chain, Reentrancy vectors through borrowAToken.transferFrom callbacks |
Invalid JSON in Claude response (stop_reason: end_turn, outputTokens: 10101)
How this affects your report: findings normally surfaced by this specialist are missing; overlapping coverage from other agents still applies.
Invalid JSON in Claude response (stop_reason: end_turn, outputTokens: 16196)
How this affects your report: findings normally surfaced by this specialist are missing; overlapping coverage from other agents still applies.
Request was aborted.
How this affects your report: findings normally surfaced by this specialist are missing; overlapping coverage from other agents still applies.
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/ba4c0384-7f22-42f5-ae08-f21864ddd511)
<a href="https://walletguard.ai/audit/ba4c0384-7f22-42f5-ae08-f21864ddd511"> <img src="https://walletguard.ai/api/badge/ba4c0384-7f22-42f5-ae08-f21864ddd511" alt="WalletGuard Audit Badge" /> </a>