{
  "schema": "avax-skills.read-only-contract-review.v1",
  "review_date_utc": "2026-09-06",
  "status": "read_only_review_complete_execution_not_performed",
  "classification": "Scoped internal educational source and test-coverage review; not a third-party audit",
  "previous_seeded_exercise": {
    "status": "blocked_and_stopped",
    "counts_as_exploit_evaluation": false,
    "statement": "The previous seeded-exploit exercise was blocked and explicitly replaced by this narrower read-only task. This report does not establish exploit-discovery, exploit-reproduction, remediation, or regression capability against seeded vulnerabilities.",
    "seeded_fixtures_accessed_by_this_reviewer": false,
    "exploit_code_created": false,
    "attack_simulations_executed": false,
    "tests_executed_by_this_reviewer": false
  },
  "scope": {
    "root": ".",
    "sources": [
      {
        "path": "examples/core/contracts/DepositVault.sol",
        "sha256": "60ddf23129b5d9a5b0ca230f7c3746ebbc578f6b6363680614a874a0bb59ada3",
        "role": "Immutable-asset educational custody ledger"
      },
      {
        "path": "examples/core/contracts/DemoToken.sol",
        "sha256": "ada5f400505fdfc317e0bc341196dfbe28363c77576abdfa565e4e7086ac7625",
        "role": "Educational six-decimal token with immutable deploying minter"
      },
      {
        "path": "examples/core/test/DepositVault.t.sol",
        "sha256": "eb18fbcae2d91b3997168fa24e3ddf25d393d78c0ad114a57034ad8fa642c2e8",
        "role": "Existing test assertions and local token doubles, inspected as text only"
      }
    ],
    "skills": [
      {
        "path": "content/audit/SKILL.md",
        "sha256": "d36d93ed328d325647407c80f12e07d6526680a225a59ba88bfc7b2315a21bd8"
      },
      {
        "path": "content/security/SKILL.md",
        "sha256": "bb4350dad1424022312f661190dc4767db7ceb889b2b7c07cb6029558a92511f"
      }
    ],
    "supporting_documents_read": [
      "content/architecture/SKILL.md",
      "content/upgrades/SKILL.md",
      "examples/core/foundry.toml"
    ],
    "compiler_configuration_observed": {
      "source_pragma": "0.8.30",
      "configured_solc": "../../.tooling/solc-0.8.30",
      "configured_evm_version": "cancun",
      "optimizer": true,
      "optimizer_runs": 200,
      "offline": true,
      "compiler_execution_verified_here": false
    },
    "deployment_addresses": [],
    "chain_behavior_verified": false,
    "source_or_test_modifications": false,
    "public_interactions": false,
    "sibling_benchmark_or_core_reports_read": false,
    "only_output_written": "research/parity-audit/read-only-review.json"
  },
  "summary": {
    "existing_test_functions_inspected": 9,
    "existing_fuzz_test_functions_inspected": 1,
    "independently_observed_runtime_passes": null,
    "confirmed_exploitable_findings": 0,
    "interpretation": "Zero confirmed exploitable findings is not a clean security bill: this task prohibited executable counterexamples and did not execute the existing suite. Source-level protections are coherent for the stated exact-transfer, stable-balance asset assumptions, but those assumptions and several failure paths need stronger evidence.",
    "principal_observations": [
      "The source uses one shared reentrancy lock on both value-moving entry points, credits deposits after checking the vault receipt, and debits owner credit before withdrawal external calls.",
      "Existing tests include meaningful owner authorization, gifts, basic input rejection, missing allowance, a mint restriction, two callback directions, inexact incoming transfer rejection, a false incoming return, and an amount-dependent conservation property.",
      "The advertised rejection of fee/rebasing assets is broader than the implemented per-operation balance-delta checks can establish.",
      "The most consequential missing evidence concerns withdrawal-failure rollback, optional and malformed token returns, and multi-user operation sequences with a complete balance-and-credit model."
    ]
  },
  "trust_and_authority_map": [
    {
      "subject": "Vault deployer",
      "power": "Selects the immutable asset address once; constructor checks code presence, not token semantics.",
      "locations": ["examples/core/contracts/DepositVault.sol:25"],
      "residual_assumption": "The selected token must report honest balances, retain supported behavior, and transfer exact amounts with stable balances. Contract code presence alone cannot prove this."
    },
    {
      "subject": "Depositor",
      "power": "Spends their own token allowance to credit any valid receiver. A gift transfers ledger withdrawal authority to the receiver.",
      "locations": ["examples/core/contracts/DepositVault.sol:37"]
    },
    {
      "subject": "Ledger owner",
      "power": "Withdraws only their own deposits mapping entry and may direct delivery to another valid receiver.",
      "locations": ["examples/core/contracts/DepositVault.sol:50"]
    },
    {
      "subject": "Asset contract",
      "power": "Controls balance reporting and transfer success; is called externally on every value-moving path. Immutable asset identity does not prove an arbitrary selected asset has immutable behavior.",
      "locations": ["examples/core/contracts/DepositVault.sol:40", "examples/core/contracts/DepositVault.sol:56", "examples/core/contracts/DepositVault.sol:66"]
    },
    {
      "subject": "DemoToken minter",
      "power": "Immutable deploying account can mint without a supply cap to any nonzero address. It has no special vault-withdrawal or token-confiscation entry point in the inspected source.",
      "locations": ["examples/core/contracts/DemoToken.sol:20", "examples/core/contracts/DemoToken.sol:22"],
      "residual_assumption": "DUSD is a demo name, not evidence of a dollar peg, redemption reserve, or monetary backing."
    },
    {
      "subject": "Absent mechanisms",
      "power": "No vault owner setter, proxy upgrade, pause, sweep, signatures, oracle, share price, loan, native-AVAX handler, or cross-chain path appears in the scoped source.",
      "residual_assumption": "Deployment, frontend, RPC, validator and third-party token-admin powers were not inspected."
    }
  ],
  "invariants": [
    {
      "id": "INV-LEDGER",
      "property": "totalDeposits equals the sum of all users' deposits after each completed transition.",
      "rationale": "Deposit increments one receiver credit and the total by the same amount. Withdrawal decrements only msg.sender credit and the total by the same amount.",
      "locations": ["examples/core/contracts/DepositVault.sol:44", "examples/core/contracts/DepositVault.sol:54"],
      "existing_evidence": "Single-user totals are asserted in the happy path and fuzz case; gift completion checks a zero total.",
      "gap": "No tracked multi-user sum across generated operation sequences."
    },
    {
      "id": "INV-BACKING",
      "property": "For an honest exact-transfer, stable-balance token, vault token balance is at least totalDeposits; equality is expected only without donations or unrelated inflows.",
      "rationale": "Accepted deposits increase backing and liabilities equally; accepted withdrawals reduce both equally. A direct donation increases backing without assigning ledger credit.",
      "locations": ["examples/core/contracts/DepositVault.sol:40", "examples/core/contracts/DepositVault.sol:56"],
      "existing_evidence": "The happy path and fuzz case check equality in environments without donations.",
      "gap": "The source's general asset assumptions and donation behavior are not tested. Equality should not be presented as universal."
    },
    {
      "id": "INV-DEPOSIT",
      "property": "A successful deposit increases the vault token balance, the selected receiver credit, and totalDeposits by exactly amount.",
      "rationale": "The token receipt is checked before crediting. The payer's own token decrease is not measured by the vault; exact payer behavior is an asset assumption.",
      "locations": ["examples/core/contracts/DepositVault.sol:37"],
      "existing_evidence": "Happy path, gift, fee-rejection and fuzz assertions cover parts of the property.",
      "gap": "No consistent complete pre/post snapshot of payer balance, receiver credit, vault balance and allowance."
    },
    {
      "id": "INV-WITHDRAW",
      "property": "A successful withdrawal reduces only the caller's ledger credit and totalDeposits by amount, reduces vault token balance by amount, and increases the valid receiver's balance by amount.",
      "rationale": "Ownership is msg.sender-based, the amount is bounded by that entry, and both sides of the token transfer have checked deltas.",
      "locations": ["examples/core/contracts/DepositVault.sol:50"],
      "existing_evidence": "Happy path checks destination receipt and remaining owner credit; fuzz checks remaining vault balance, total and owner credit.",
      "gap": "Receiver and payer external balances are absent from the fuzz assertions; no generated multi-owner isolation property."
    },
    {
      "id": "INV-FAILURE-ATOMICITY",
      "property": "A rejected deposit or withdrawal must leave token balances, relevant allowances, totalDeposits and all involved credits unchanged.",
      "rationale": "Withdrawal updates liabilities before external token interaction, so atomic failure is essential to preserve claims. Rejecting the transaction must not merely produce the expected error while leaving a changed accounting state.",
      "locations": ["examples/core/contracts/DepositVault.sol:54", "examples/core/contracts/DepositVault.sol:66"],
      "existing_evidence": "Fee rejection checks totalDeposits and payer balance; missing allowance checks receiver credit and total; false return checks only total.",
      "gap": "No failed-withdrawal full-state assertions; the existing negative deposit tests also omit several relevant state components."
    },
    {
      "id": "INV-CALLBACK",
      "property": "Neither value-moving entry point can execute recursively while either value-moving operation holds the common lock.",
      "rationale": "Both external operations use the same entered storage variable, covering shared-entry and cross-entry calls structurally.",
      "locations": ["examples/core/contracts/DepositVault.sol:30", "examples/core/contracts/DepositVault.sol:37", "examples/core/contracts/DepositVault.sol:50"],
      "existing_evidence": "The existing callback test checks deposit-to-deposit and withdrawal-to-withdrawal rejection selectors and a final total of 500.",
      "gap": "Cross-entry rejection, complete final asset/credit reconciliation, and continued usability following a rejected outer operation are not explicitly asserted. Public getters remain observable during callbacks; no external consumer of their transient state is in scope."
    },
    {
      "id": "INV-TOKEN",
      "property": "Only minter can increase totalSupply; mint adds the same amount to supply and one balance; ordinary transfers conserve the sum of balances; successful transferFrom consumes the spender's allowance by amount.",
      "rationale": "The minter is immutable and the three accounting transitions are directly visible in DemoToken.",
      "locations": ["examples/core/contracts/DemoToken.sol:22", "examples/core/contracts/DemoToken.sol:42", "examples/core/contracts/DemoToken.sol:51"],
      "existing_evidence": "Unauthorized mint is tested; transfers are exercised indirectly by vault tests.",
      "gap": "No direct supply-sum, allowance accounting, token event, transfer-to-self, or failed-transfer rollback assertions."
    }
  ],
  "existing_test_review": [
    {
      "name": "testDepositWithdrawAndAuthorization",
      "location": "examples/core/test/DepositVault.t.sol:48",
      "value": "Meaningful credit, unauthorized withdrawal rejection, directed payment and backing-equality assertions.",
      "limitation": "One depositor and one partial withdrawal; unauthorized failure state is not independently snapshotted."
    },
    {
      "name": "testGiftDepositOnlyReceiverCanWithdraw",
      "location": "examples/core/test/DepositVault.t.sol:56",
      "value": "Separates payer from withdrawal owner and exercises full gift redemption.",
      "limitation": "No simultaneous remaining balances for several owners."
    },
    {
      "name": "testRejectZeroAmountsAndAddresses",
      "location": "examples/core/test/DepositVault.t.sol:62",
      "value": "Checks zero amount, deposit zero/self receiver, withdrawal self receiver, and code-less asset constructor errors.",
      "limitation": "Missing withdrawal zero receiver and contract-without-token-interface behavior."
    },
    {
      "name": "testMissingAllowanceCannotCreateDeposit",
      "location": "examples/core/test/DepositVault.t.sol:70",
      "value": "Rejects unsupported spend and verifies no new receiver or total credit.",
      "limitation": "No complete token-balance or allowance snapshot; insufficient balance after allowance approval is a distinct missing case."
    },
    {
      "name": "testMinterAuthorization",
      "location": "examples/core/test/DepositVault.t.sol:75",
      "value": "Explicit unauthorized mint rejection.",
      "limitation": "No positive supply accounting assertion, zero-recipient mint test, or complete state snapshot."
    },
    {
      "name": "testReentrantCallbacksBlockedOnDepositAndWithdrawal",
      "location": "examples/core/test/DepositVault.t.sol:78",
      "value": "Checks the specific common-lock error on both tested callback directions while the outer operation continues.",
      "limitation": "Final total alone does not verify full balance/credit conservation; cross-entry directions are not asserted. Existing code was inspected only, not executed here."
    },
    {
      "name": "testFeeOnTransferRejectedAtomically",
      "location": "examples/core/test/DepositVault.t.sol:88",
      "value": "Checks inexact incoming receipt rejection plus payer-balance and aggregate-liability rollback.",
      "limitation": "FeeToken's transferFrom does not check or consume allowance, so this test cannot prove allowance rollback. It covers incoming short receipt, not all fee or rebase behaviors."
    },
    {
      "name": "testFalseReturnRejected",
      "location": "examples/core/test/DepositVault.t.sol:94",
      "value": "Checks a false transferFrom result is not accepted or credited.",
      "limitation": "The double performs no transfer before returning false. This does not independently demonstrate rollback of an already attempted token-state change, and it does not exercise transfer on withdrawal."
    },
    {
      "name": "testFuzzConservation",
      "location": "examples/core/test/DepositVault.t.sol:99",
      "value": "A genuine generated-input property: the retained user credit, total liability and vault token balance must all equal deposited minus withdrawn. It is more than a fixed happy-path test.",
      "limitation": "The generated values are reduced to a deposit in 1..10,000,000 and a withdrawal in 1..deposited; there is one fixed caller, receiver, deposit and withdrawal. It is not a stateful multi-operation invariant campaign and does not measure receiver receipt, payer outflow, allowance, donations, rejected operations, or near-uint256 limits."
    }
  ],
  "correctness_observations": [
    {
      "id": "RO-01",
      "title": "Asset-rejection documentation exceeds the enforced checks",
      "classification": "Confirmed source/documentation mismatch; no exploit demonstrated",
      "severity": "informational",
      "locations": ["examples/core/contracts/DepositVault.sol:9", "examples/core/contracts/DepositVault.sol:25", "examples/core/contracts/DepositVault.sol:40", "examples/core/contracts/DepositVault.sol:56"],
      "prerequisites": "An integrator reads the comment as a guarantee that any fee-bearing or rebasing asset class is detected and rejected automatically.",
      "evidence": "The constructor only checks code presence. Runtime checks compare balances immediately around individual transfers. They do not inspect asset classes, validate long-term balance stability, measure payer balance on deposit, or compare global backing to liabilities before every operation.",
      "impact": "An integrator can overestimate asset admission guarantees. Stable balances and supported fee semantics must remain explicit external assumptions; this source review does not establish a concrete loss scenario.",
      "remediation": "Describe fee/rebasing assets as unsupported and state exactly which per-operation deltas are enforced. Document that the selected asset must be vetted for persistent exact-transfer, honest-balance and stable-balance behavior. Do not characterize snapshots as general rebase detection.",
      "verification": "Source comparison only; no behavioral reproduction or fix applied.",
      "regression_status": "not_run"
    },
    {
      "id": "RO-02",
      "title": "Token error normalization has an untested decoding boundary",
      "classification": "Source-level interface/error-semantics consideration, not a confirmed security vulnerability",
      "severity": "informational",
      "locations": ["examples/core/contracts/DepositVault.sol:66"],
      "prerequisites": "A token returns a 32-byte value that cannot be decoded as a canonical ABI boolean, or an integration assumes every failed token operation yields TokenCallFailed.",
      "evidence": "The helper checks length and invokes abi.decode(result, (bool)) inside the conditional. There is no separate canonical-word validation or explicit normalization around decoding. Existing tests exercise false returns but not malformed data.",
      "impact": "The TokenCallFailed selector should not be promised uniformly for all malformed-return and balanceOf failures without checking the actual compiler/runtime behavior. Exact revert bytes for the malformed-boolean case were not verified in this task; no funds impact is demonstrated.",
      "remediation": "Define whether a stable custom error is part of the intended interface, then cover optional, false and malformed return cases as compatibility tests. If stable normalization is required, use a reviewed transfer helper or explicit return validation in a separately authorized change.",
      "verification": "Static observation only; runtime error classification remains unverified.",
      "regression_status": "not_run"
    }
  ],
  "prioritized_coverage_gaps": [
    {
      "id": "GAP-01",
      "priority": "high_evidence_priority_not_vulnerability_severity",
      "area": "Withdrawal rejection and atomic accounting",
      "desired_property": "On a failed or inexact outbound transfer, owner credit, total liabilities, vault/receiver balances and other users' claims are unchanged; a later ordinary operation remains usable.",
      "why": "Withdrawal mutates liabilities before the token call and therefore relies critically on complete transaction rollback.",
      "implementation_status": "recommendation_only_no_code_created"
    },
    {
      "id": "GAP-02",
      "priority": "high_evidence_priority_not_vulnerability_severity",
      "area": "Generated multi-user operation sequences",
      "desired_property": "Track each participant's expected credit, payer/receiver token changes, allowances and surplus after sequences of deposits, gifts, partial/full withdrawals, and rejected requests; assert the ledger sum and backing inequality after each completed step.",
      "why": "The current fuzz property is meaningful but cannot exercise ordering, repeated interactions or simultaneous owner isolation.",
      "implementation_status": "recommendation_only_no_code_created"
    },
    {
      "id": "GAP-03",
      "priority": "medium_evidence_priority_not_vulnerability_severity",
      "area": "Token return and balance-reporting compatibility",
      "desired_property": "Define and verify accepted empty and true returns, rejected false and malformed returns, balanceOf failures, and the effect of each on complete state snapshots for both deposit and withdrawal.",
      "why": "The custom helper accepts optional return data, but the current suite only demonstrates an ordinary true return and an incoming false return at source level.",
      "implementation_status": "recommendation_only_no_code_created"
    },
    {
      "id": "GAP-04",
      "priority": "medium_evidence_priority_not_vulnerability_severity",
      "area": "Callback regression completeness",
      "desired_property": "Keep the shared-lock invariant explicit for both entry points and reconcile all final balances/credits in the existing callback regression; distinguish tested callback directions from source-level coverage of other directions.",
      "why": "Checking an error selector and aggregate total is narrower than showing the whole custody invariant survives the callback and outer transfer.",
      "implementation_status": "recommendation_only_no_code_created"
    },
    {
      "id": "GAP-05",
      "priority": "medium_evidence_priority_not_vulnerability_severity",
      "area": "Unsupported asset and donation assumptions",
      "desired_property": "Clearly separate transaction-local exact deltas from long-term asset assumptions; establish that a direct donation grants no ledger claim and changes equality to surplus-aware backing inequality.",
      "why": "The code has no surplus recovery entry point, and a transfer made directly to the vault is not a deposit. That is an integration and recovery limitation, not proof of theft.",
      "implementation_status": "recommendation_only_no_code_created"
    },
    {
      "id": "GAP-06",
      "priority": "lower_evidence_priority_not_vulnerability_severity",
      "area": "Boundary, allowance, event and DemoToken behavior",
      "desired_property": "Cover withdrawal to zero, withdrawal just above a nonzero balance, insufficient token balance with adequate allowance, larger amount boundaries, zero-address token operations, transfer-to-self, exact allowance use including maximum approval semantics, supply conservation and emitted event arguments.",
      "why": "These increase interface and accounting confidence. Maximum approval is decremented in the inspected DemoToken; preserving that specified behavior is a compatibility decision, not a finding that infinite approval must be implemented.",
      "implementation_status": "recommendation_only_no_code_created"
    }
  ],
  "skill_alignment": {
    "performed": [
      "Bounded source/compiler-configuration scope and local hashes",
      "Entry-point, asset and authority mapping",
      "Transition-specific invariant rationale",
      "Examination of actual token return handling and external calls",
      "Inspection of whether the existing fuzz assertions are meaningful",
      "Evidence locations, severity restraint and explicit omissions"
    ],
    "not_performed_due_to_revised_scope": [
      "Executable counterexamples required by the full audit workflow",
      "Seeded-vulnerability discovery or scoring",
      "Source repair and post-fix regressions",
      "Any test execution, attack simulation or public interaction"
    ],
    "out_of_scope_failure_domains": [
      "No share/debt math, yield, exchange rate, oracle, swap, signature or replay path exists in the inspected contracts.",
      "No upgrade, pause, liquidation, cross-chain authentication or sovereign-L1 precompile integration exists in the inspected contracts.",
      "C-Chain/Fuji/mainnet activation, deployed bytecode and external infrastructure were not verified; the Cancun build setting is only an observed local configuration."
    ]
  },
  "limitations": [
    "This is a read-only educational review, not an exploit evaluation, full protocol audit, independent runtime certification, or unknown-vulnerability guarantee.",
    "No source/test changes, executable reproductions, fixes or regression executions were performed by this reviewer.",
    "The parent agent is responsible for independently verifying existing tests. Any parent result should be tied to the exact source hashes and distinguished from this static review.",
    "No seeded fixture or sibling benchmark/core report contents were inspected, preserving the narrowed boundary and review independence.",
    "The token doubles are simplified local models; they do not establish behavior of any live token, callback standard, externally administered token, fork, or upstream protocol.",
    "No stateful invariant run count, coverage percentage, fuzz seed, gas profile or compiler output was observed here.",
    "Contract names, demo token symbols and configured EVM targets are not evidence of deployment, economic backing, chain compatibility or production readiness."
  ]
}
