{
  "tool_id": "art-610-erc4626-vault-share-math",
  "tool_version": "1.0.0",
  "display_name": "ERC-4626 Vault Share Math",
  "mcp_name": "recompute_erc4626_vault_share_math",
  "mandate_type": "payment_policy",
  "wave": 99,
  "gpu": false,
  "url": "https://ainumbers.co/chaingraph/art-610-erc4626-vault-share-math.html",
  "description": "Recomputes ERC-4626 tokenized-vault share and asset conversions from caller-declared vault state (total_assets, total_supply, optional virtual-amounts offset), applying the rounding direction the standard mandates for each function and reporting which direction produced each result alongside what the opposite direction would have produced. ERC-4626 (Final, Created 2021-12-22, CC0-1.0) fixes those directions per function: convertToShares and convertToAssets round down towards 0, previewDeposit returns no more than the shares a deposit would mint and previewRedeem no more than the assets a redeem would withdraw (both round down), while previewMint returns no fewer than the assets a mint would deposit and previewWithdraw no fewer than the shares a withdraw would burn (both round up). Getting one direction backwards is how a vault leaks value, so each is checked separately. Also computes a deposit-then-redeem round-trip loss bound against the post-deposit state, a signed exchange-rate drift between two declared snapshots, and a declared fee application. All arithmetic is exact uint256 integer math with no floating point. This node never reads any chain: it cannot know whether the declared totals match a deployed vault, whether that vault applies these directions, or whether a rate change came from yield, loss, a donation, or an attack.",
  "input_schema_ref": "chaingraph/art-610-erc4626-vault-share-math.html#manifest",
  "consumes": [],
  "feeds": [],
  "status": "live",
  "conformance_fixtures": true,
  "compute_capability": "server",
  "compute_images": [{"system":"sha256-source","image_id":"sha256:b112b2136dc497e69f632232e47a9a70fa63d7dbc3d67c313cf89edb1fb97f33","valid_from":"2026-08-11"},{"system":"risc0","image_id":"sha256:a1a0bc89b5b1febaeda3519f6dbade0fa5ac16beeb143c4e1b01689573567bc6","valid_from":"2026-08-12"}],
  "export_capability": [
    "json"
  ],
  "compute_proof": {
    "type": "ZkVmReceipt",
    "system": "risc0",
    "receiptFormat": "groth16-bn254",
    "imageId": "sha256:a1a0bc89b5b1febaeda3519f6dbade0fa5ac16beeb143c4e1b01689573567bc6",
    "seal": "FnJqQnhZy76bVkvzmYiAACydxrN9RUYhxw4zNJzhhr4pLI6hDUPeNwI51Ya5ECyPpssBNECQOmye6BM6Xxi9qAiTiV6bBUfMBAhoX5euqwU2XM6nITpS0SOw9o0U2ujQEj3AXKbZ+UiQMQRMN87cjvULIv97Ly8fWTgnkQyrIKYpYueTxBJwRPsuuSrS8pHxBqVbCOrADHxqZ+Z1AKCnmQ1zfNmdsYlaDaEZ2+aFjqJWexI8GJICt9R0mD/AW5v+Dk3zbGIqOCA+KagVeSnjEfn3NSnO9qCOct/6K/1bXAEbhfZX+E7EJpImENeBypDJt77vujBKYhSKRiHIGmT2Xw==",
    "journal": {
      "chaingraph_version": "0.4.0",
      "kernel_digest": "sha256:b112b2136dc497e69f632232e47a9a70fa63d7dbc3d67c313cf89edb1fb97f33",
      "output": {
        "conversions": [
          {
            "eip_rule": "MUST round down towards 0",
            "input": "1000",
            "op": "convertToShares",
            "output": "333",
            "output_if_rounded_other_way": "334",
            "rounding_changes_result": true,
            "rounding_direction": "down",
            "side": "assets_to_shares"
          },
          {
            "eip_rule": "MUST round down towards 0",
            "input": "1000",
            "op": "convertToAssets",
            "output": "3003",
            "output_if_rounded_other_way": "3004",
            "rounding_changes_result": true,
            "rounding_direction": "down",
            "side": "shares_to_assets"
          },
          {
            "eip_rule": "MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit call",
            "input": "1000",
            "op": "previewDeposit",
            "output": "333",
            "output_if_rounded_other_way": "334",
            "rounding_changes_result": true,
            "rounding_direction": "down",
            "side": "assets_to_shares"
          },
          {
            "eip_rule": "MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call",
            "input": "1000",
            "op": "previewMint",
            "output": "3004",
            "output_if_rounded_other_way": "3003",
            "rounding_changes_result": true,
            "rounding_direction": "up",
            "side": "shares_to_assets"
          },
          {
            "eip_rule": "MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw call",
            "input": "1000",
            "op": "previewWithdraw",
            "output": "334",
            "output_if_rounded_other_way": "333",
            "rounding_changes_result": true,
            "rounding_direction": "up",
            "side": "assets_to_shares"
          },
          {
            "eip_rule": "MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call",
            "input": "1000",
            "op": "previewRedeem",
            "output": "3003",
            "output_if_rounded_other_way": "3004",
            "rounding_changes_result": true,
            "rounding_direction": "down",
            "side": "shares_to_assets"
          }
        ],
        "declared_context": {
          "chain_id": "1",
          "network_label": "declared label, not a selector"
        },
        "fee": null,
        "note": "Recomputes ERC-4626 share/asset conversions from caller-declared vault state, applying the per-function rounding directions ERC-4626 mandates (convertToShares/convertToAssets/previewDeposit/previewRedeem round down; previewMint/previewWithdraw round up) and reporting the direction used for each. This kernel does NOT read any chain: it cannot know whether the declared total_assets/total_supply match any deployed vault, whether that vault's own implementation actually applies these directions, whether a rate change between two declared snapshots came from yield, loss, donation or an attack, or whether the declared fee basis points are the fee a vault really charges. Round-trip loss and zero-share-mint findings are properties of the declared numbers under the standard's arithmetic, not an audit of any deployment.",
        "rate_drift": null,
        "reasons": [],
        "round_trip": null,
        "rounding_table": [
          {
            "direction": "down",
            "eip_rule": "MUST round down towards 0",
            "op": "convertToAssets"
          },
          {
            "direction": "down",
            "eip_rule": "MUST round down towards 0",
            "op": "convertToShares"
          },
          {
            "direction": "down",
            "eip_rule": "MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit call",
            "op": "previewDeposit"
          },
          {
            "direction": "up",
            "eip_rule": "MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call",
            "op": "previewMint"
          },
          {
            "direction": "down",
            "eip_rule": "MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call",
            "op": "previewRedeem"
          },
          {
            "direction": "up",
            "eip_rule": "MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw call",
            "op": "previewWithdraw"
          }
        ],
        "vault_state": {
          "decimals_offset_used": "0",
          "total_assets": "1000000000000000000000",
          "total_supply": "333000000000000000000",
          "virtual_amounts_used": true,
          "virtual_assets": "1",
          "virtual_shares": "1"
        }
      }
    }
  }
}
