{
  "address": "A5SYMN5DGKWo8oPwDgWUxCZHZA7TaCkLbguSrLiWc91",
  "metadata": {
    "name": "rwa_vault",
    "version": "0.1.0",
    "spec": "0.1.0",
    "description": "RWA vault program (per-asset token + payout custody)"
  },
  "instructions": [
    {
      "name": "approve_trading",
      "docs": [
        "Grant `delegate` (the market Asset PDA) authority to move the vault's RWA + payout",
        "token accounts — the EVM \"Vault approves Market\" allowance. Owner (multisig) only.",
        "Lets the market execute non-custodial buy/sell without custody leaving the vault.",
        "# CLOSED: this grants NOTHING any more",
        "",
        "This grants the market's Asset PDA a `u64::MAX` delegate over the vault's stock ATA, so",
        "`rwa_market::buy` moves inventory by SPL delegate transfer without entering this program",
        "at all. No check here can see it, which means a retail buy can sell stock a maker has",
        "already delivered into a redemption queue, leaving the phase-3 return with nothing to",
        "return and — under the venue's strict FIFO — the queue frozen behind it.",
        "",
        "Bounding it would mean approving only the free balance and re-approving on every",
        "`credit_return` / `consume_return`, since SPL has no partial-delegate accounting. That",
        "is a large change with its own failure mode: any missed re-approval halts trading.",
        "Recorded here deliberately rather than quietly accepted — the EVM vault closes this path",
        "through `withdrawToken`, so the two chains genuinely differ, and the Solana side relies",
        "on the vault holding inventory well above the queue rather than on an enforced floor."
      ],
      "discriminator": [
        250,
        99,
        1,
        208,
        197,
        1,
        134,
        7
      ],
      "accounts": [
        {
          "name": "owner",
          "signer": true
        },
        {
          "name": "vault",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "delegate"
        },
        {
          "name": "rwa_mint"
        },
        {
          "name": "payout_mint"
        },
        {
          "name": "vault_rwa_ata",
          "writable": true
        },
        {
          "name": "vault_payout_ata",
          "writable": true
        },
        {
          "name": "rwa_token_program"
        },
        {
          "name": "payout_token_program"
        }
      ],
      "args": []
    },
    {
      "name": "consume_return",
      "docs": [
        "Record that `amount` was paid for, so it is no longer owed back."
      ],
      "discriminator": [
        48,
        213,
        53,
        178,
        166,
        145,
        40,
        82
      ],
      "accounts": [
        {
          "name": "venue",
          "signer": true
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "allowance",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  97,
                  108,
                  108,
                  111,
                  119,
                  97,
                  110,
                  99,
                  101
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              },
              {
                "kind": "account",
                "path": "venue"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "credit_owed_payment",
      "docs": [
        "Move payout tokens out of the vault, against the caller's allowance.",
        "Record cash a venue owes a maker because a resolution deferred the payout.",
        "Record cash a venue owes a maker, and CHARGE THE BUDGET FOR IT NOW.",
        "",
        "The allowance moves here, not at delivery. Charging it at delivery meant two things, both",
        "wrong: lowering the allowance after a resolution stranded cash the maker had already",
        "delivered its stock for, and several resolutions could each pass against the same",
        "un-decremented budget. The decision is the commitment, so the budget moves with the",
        "decision (R3-1). `available_float` is bounded by what is left, so the next head sees a",
        "smaller float immediately — which is the behaviour the float check always claimed."
      ],
      "discriminator": [
        120,
        21,
        196,
        79,
        113,
        219,
        21,
        162
      ],
      "accounts": [
        {
          "name": "venue",
          "docs": [
            "The venue, signing as its own PDA through a CPI."
          ],
          "signer": true
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "allowance",
          "docs": [
            "`mut` since R3-1: `credit_owed_payment` now charges `payout_remaining` and records",
            "`owed_payment` here. Anchor only serialises accounts marked `mut`, so without it those",
            "writes were made to the in-memory copy and SILENTLY DISCARDED on exit — no error, just",
            "a budget that never moved and a debt that was never recorded."
          ],
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  97,
                  108,
                  108,
                  111,
                  119,
                  97,
                  110,
                  99,
                  101
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              },
              {
                "kind": "account",
                "path": "venue"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "credit_return",
      "docs": [
        "Record that `amount` of stock arrived from a maker and is owed back."
      ],
      "discriminator": [
        205,
        37,
        34,
        77,
        107,
        166,
        127,
        126
      ],
      "accounts": [
        {
          "name": "venue",
          "signer": true
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "allowance",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  97,
                  108,
                  108,
                  111,
                  119,
                  97,
                  110,
                  99,
                  101
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              },
              {
                "kind": "account",
                "path": "venue"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "draw_owed_payment",
      "docs": [
        "Deliver cash a resolution already recorded. Against the DEBT, never the budget.",
        "",
        "The twin of `draw_return` on the stock side, and ungated for the same reason: a caller",
        "holding no debt can do nothing here, so the debt is its own authorisation. It does not",
        "consult `free_payment`, because this money is precisely what `free_payment` holds back."
      ],
      "discriminator": [
        39,
        64,
        83,
        93,
        156,
        212,
        15,
        124
      ],
      "accounts": [
        {
          "name": "venue",
          "signer": true
        },
        {
          "name": "vault",
          "docs": [
            "`mut` since R3-1: `draw_owed_payment` shares this context and decrements",
            "`total_owed_payment`. `draw_payment` only reads it, but the two cannot have different",
            "account lists, and a silently-discarded write is the worse failure mode."
          ],
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "allowance",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  97,
                  108,
                  108,
                  111,
                  119,
                  97,
                  110,
                  99,
                  101
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              },
              {
                "kind": "account",
                "path": "venue"
              }
            ]
          }
        },
        {
          "name": "payout_mint"
        },
        {
          "name": "vault_payout_ata",
          "writable": true
        },
        {
          "name": "destination",
          "writable": true
        },
        {
          "name": "payout_token_program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "draw_payment",
      "docs": [
        "Discharge recorded cash once `withdraw_owed` has actually paid it out."
      ],
      "discriminator": [
        139,
        163,
        85,
        1,
        251,
        107,
        55,
        58
      ],
      "accounts": [
        {
          "name": "venue",
          "signer": true
        },
        {
          "name": "vault",
          "docs": [
            "`mut` since R3-1: `draw_owed_payment` shares this context and decrements",
            "`total_owed_payment`. `draw_payment` only reads it, but the two cannot have different",
            "account lists, and a silently-discarded write is the worse failure mode."
          ],
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "allowance",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  97,
                  108,
                  108,
                  111,
                  119,
                  97,
                  110,
                  99,
                  101
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              },
              {
                "kind": "account",
                "path": "venue"
              }
            ]
          }
        },
        {
          "name": "payout_mint"
        },
        {
          "name": "vault_payout_ata",
          "writable": true
        },
        {
          "name": "destination",
          "writable": true
        },
        {
          "name": "payout_token_program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "draw_return",
      "docs": [
        "Hand stock back to a maker, against the RETURN CREDIT and not the creation allowance."
      ],
      "discriminator": [
        209,
        55,
        82,
        215,
        108,
        179,
        105,
        111
      ],
      "accounts": [
        {
          "name": "venue",
          "docs": [
            "The venue, signing as its own PDA through a CPI."
          ],
          "signer": true
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "allowance",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  97,
                  108,
                  108,
                  111,
                  119,
                  97,
                  110,
                  99,
                  101
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              },
              {
                "kind": "account",
                "path": "venue"
              }
            ]
          }
        },
        {
          "name": "rwa_mint"
        },
        {
          "name": "vault_rwa_ata",
          "writable": true
        },
        {
          "name": "destination",
          "writable": true
        },
        {
          "name": "rwa_token_program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "draw_stock",
      "discriminator": [
        225,
        52,
        25,
        35,
        86,
        240,
        111,
        98
      ],
      "accounts": [
        {
          "name": "venue",
          "docs": [
            "The venue, signing as its own PDA through a CPI."
          ],
          "signer": true
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "allowance",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  97,
                  108,
                  108,
                  111,
                  119,
                  97,
                  110,
                  99,
                  101
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              },
              {
                "kind": "account",
                "path": "venue"
              }
            ]
          }
        },
        {
          "name": "rwa_mint"
        },
        {
          "name": "vault_rwa_ata",
          "writable": true
        },
        {
          "name": "destination",
          "writable": true
        },
        {
          "name": "rwa_token_program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "init_config",
      "docs": [
        "Bind this program to its governing authority. Callable ONCE, and only by the program's",
        "current upgrade authority.",
        "",
        "Gating on the upgrade authority is what makes the bootstrap safe: at deploy time that is",
        "the deploy wallet, and after the Squads handoff it is the multisig vault. The only party",
        "who can claim a program's Config is therefore the same party who can already replace its",
        "bytecode. A permissionless `init_config` would simply move the first-caller-wins hole",
        "from the per-asset PDAs up to the global one."
      ],
      "discriminator": [
        23,
        235,
        115,
        232,
        168,
        96,
        1,
        231
      ],
      "accounts": [
        {
          "name": "payer",
          "writable": true,
          "signer": true
        },
        {
          "name": "upgrade_authority",
          "docs": [
            "Must be this program's current upgrade authority."
          ],
          "signer": true
        },
        {
          "name": "program_data"
        },
        {
          "name": "config",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  111,
                  110,
                  102,
                  105,
                  103
                ]
              }
            ]
          }
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        }
      ],
      "args": [
        {
          "name": "authority",
          "type": "pubkey"
        },
        {
          "name": "operator",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "init_vault",
      "docs": [
        "Create the vault PDA for `mint`. Mirrors VaultFactory.createVault(token, vaultOwner).",
        "",
        "The owner is taken from `Config`, NOT from a parameter. That is the whole fix for C-1:",
        "this used to accept `owner: Pubkey` from an unauthenticated caller, so anyone could",
        "create the canonical [\"vault\", mint] PDA with themselves as owner and then drain it via",
        "`owner_withdraw` once our flow funded it. With the owner derived from Config, even an",
        "unauthorised caller who wins the race produces a vault owned by the multisig."
      ],
      "discriminator": [
        77,
        79,
        85,
        150,
        33,
        217,
        52,
        106
      ],
      "accounts": [
        {
          "name": "config",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  111,
                  110,
                  102,
                  105,
                  103
                ]
              }
            ]
          }
        },
        {
          "name": "authority",
          "docs": [
            "Operator (routine listings) or the governing authority. Gating creation as well as",
            "ownership keeps an attacker from pre-creating the PDA to make our own call fail."
          ],
          "signer": true
        },
        {
          "name": "payer",
          "writable": true,
          "signer": true
        },
        {
          "name": "mint"
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "mint"
              }
            ]
          }
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        }
      ],
      "args": [
        {
          "name": "market_program",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "market_draw_payment",
      "docs": [
        "Pay a retail seller out of the vault, on the MARKET's behalf, respecting the cash",
        "ring-fence. The payout-side twin of `market_draw_stock`, and for the same reason: the",
        "market used an SPL delegate on the vault's payout ATA, so this program never ran and",
        "could not stop a retail sell spending cash a deferred redemption already owes a maker.",
        "",
        "With this and `market_draw_stock` in place NO delegate is needed at all — see",
        "`approve_trading`."
      ],
      "discriminator": [
        149,
        4,
        25,
        195,
        151,
        44,
        19,
        106
      ],
      "accounts": [
        {
          "name": "asset",
          "signer": true
        },
        {
          "name": "vault",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "payout_mint"
        },
        {
          "name": "vault_payout_ata",
          "writable": true
        },
        {
          "name": "destination",
          "writable": true
        },
        {
          "name": "payout_token_program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "market_draw_stock",
      "docs": [
        "Release vault inventory to a retail buyer, on the MARKET's behalf, respecting the",
        "ring-fence. Signed by the vault's own PDA through a CPI from rwa_market.",
        "",
        "# Why the market no longer moves this itself",
        "",
        "`approve_trading` gives the Asset PDA an SPL delegate over the vault's stock ATA, and",
        "`rwa_market::buy` used it to transfer directly. That transfer never entered this program,",
        "so no check here could see it, and a retail buy could sell stock a maker had already",
        "delivered into a redemption queue — leaving the phase-3 return with nothing to return",
        "and, under strict FIFO, the whole queue frozen behind it.",
        "",
        "SPL delegates are all-or-nothing, so there is no allowance to bound. The fix is the one",
        "Base already had: the market asks the vault, and the vault decides. `MarketUpgradeable`",
        "calls `vault.withdrawToken()`, which checks `freeTokenBalance()`; this is that, on",
        "Solana. With `market_draw_payment` covering the other leg, NO delegate is left anywhere:",
        "`approve_trading` grants nothing and `revoke_trading` clears what was granted before."
      ],
      "discriminator": [
        58,
        211,
        226,
        166,
        255,
        8,
        230,
        202
      ],
      "accounts": [
        {
          "name": "asset",
          "docs": [
            "The market's Asset PDA, signing through a CPI. Seed-constrained against rwa_market so",
            "nothing else can pose as the market."
          ],
          "signer": true
        },
        {
          "name": "vault",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "rwa_mint"
        },
        {
          "name": "vault_rwa_ata",
          "writable": true
        },
        {
          "name": "destination",
          "writable": true
        },
        {
          "name": "rwa_token_program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "migrate_vault",
      "docs": [
        "Grow a pre-existing 73-byte `Vault` to carry `total_return_credit`. Owner only.",
        "",
        "Run this in the SAME Squads proposal as the program upgrade — a Squads BATCH is one",
        "proposal holding several transactions — but NOT in the same slot:",
        "a freshly upgraded program cannot be invoked until the next slot, so an instruction",
        "batched immediately behind the upgrade would fail outright.",
        "",
        "There IS therefore a window, and the earlier claim that there was none was simply wrong",
        "(R3-6). It runs from the vault upgrade to this call, and during it every `Vault` is",
        "unreadable — `Account<Vault>` cannot deserialise the old 73-byte account once the new",
        "code is live. Keep it to the one slot by proposing the pair together; run as separate",
        "proposals it lasts until signers return. See docs/VENUE-SPEC.md §12.1 for the order the",
        "rest of the batch has to follow, which exists for the same reason.",
        "",
        "Setting the total to zero is correct rather than convenient: `rwa_venue` is not deployed",
        "on any cluster, so no vault has ever been credited a return. A migration run after a",
        "venue is live would have to sum the allowances instead, which is why this refuses to run",
        "twice — a second call on an already-grown account would zero a real debt."
      ],
      "discriminator": [
        139,
        151,
        25,
        211,
        120,
        164,
        24,
        215
      ],
      "accounts": [
        {
          "name": "owner",
          "signer": true
        },
        {
          "name": "payer",
          "writable": true,
          "signer": true
        },
        {
          "name": "vault",
          "docs": [
            "The handler checks the program owner, the discriminator AND the [\"vault\", mint] PDA",
            "before it writes a byte; see migrate_vault."
          ],
          "writable": true
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        }
      ],
      "args": [
        {
          "name": "market_program",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "owner_withdraw",
      "docs": [
        "Withdraw custodied tokens (RWA inventory or payout liquidity) from a vault-owned",
        "token account to `destination`. Owner (multisig) only. Signed by the vault PDA.",
        "Mirrors VaultUpgradeable.ownerWithdrawPayment."
      ],
      "discriminator": [
        138,
        172,
        103,
        228,
        254,
        96,
        114,
        178
      ],
      "accounts": [
        {
          "name": "owner",
          "signer": true
        },
        {
          "name": "vault",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "token_mint",
          "docs": [
            "Mint of the token being withdrawn (may be the RWA mint OR the payout mint —",
            "a vault custodies both). Distinct from `vault.mint`, which is the vault's identity."
          ]
        },
        {
          "name": "vault_token_account",
          "writable": true
        },
        {
          "name": "destination",
          "writable": true
        },
        {
          "name": "token_program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "revoke_trading",
      "discriminator": [
        33,
        162,
        15,
        67,
        129,
        114,
        154,
        213
      ],
      "accounts": [
        {
          "name": "signer",
          "signer": true
        },
        {
          "name": "config",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  111,
                  110,
                  102,
                  105,
                  103
                ]
              }
            ]
          }
        },
        {
          "name": "vault",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "rwa_mint"
        },
        {
          "name": "payout_mint"
        },
        {
          "name": "vault_rwa_ata",
          "writable": true
        },
        {
          "name": "vault_payout_ata",
          "writable": true
        },
        {
          "name": "rwa_token_program"
        },
        {
          "name": "payout_token_program"
        }
      ],
      "args": []
    },
    {
      "name": "set_config_authority",
      "docs": [
        "Rotate the governing authority (migrating to a new Squads multisig) and/or the operator",
        "hot key. Current authority only.",
        "",
        "Every per-asset account created BEFORE a rotation keeps the old admin recorded in its own",
        "state — this only changes who may create new ones. Rotating existing assets is a separate",
        "concern (see M-1 in SECURITY-AUDIT.md)."
      ],
      "discriminator": [
        16,
        200,
        212,
        18,
        95,
        43,
        107,
        89
      ],
      "accounts": [
        {
          "name": "authority",
          "signer": true
        },
        {
          "name": "config",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  111,
                  110,
                  102,
                  105,
                  103
                ]
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "authority",
          "type": "pubkey"
        },
        {
          "name": "operator",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "set_market_program",
      "docs": [
        "Repoint a vault at a different rwa_market deployment. Owner (multisig) only.",
        "",
        "The counterpart of rwa_market's `set_venue_program`: the link between the two programs",
        "is configuration on both sides, so redeploying either is a governance call rather than a",
        "program upgrade, and neither can silently stop matching."
      ],
      "discriminator": [
        139,
        37,
        16,
        45,
        213,
        141,
        240,
        156
      ],
      "accounts": [
        {
          "name": "owner",
          "signer": true
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "market_program",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "set_venue_allowance",
      "discriminator": [
        134,
        173,
        212,
        97,
        142,
        154,
        152,
        109
      ],
      "accounts": [
        {
          "name": "owner",
          "writable": true,
          "signer": true
        },
        {
          "name": "vault",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "venue"
        },
        {
          "name": "allowance",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  97,
                  108,
                  108,
                  111,
                  119,
                  97,
                  110,
                  99,
                  101
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              },
              {
                "kind": "account",
                "path": "venue"
              }
            ]
          }
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        }
      ],
      "args": [
        {
          "name": "stock",
          "type": "u64"
        },
        {
          "name": "payout",
          "type": "u64"
        }
      ]
    },
    {
      "name": "set_venue_revoked",
      "docs": [
        "Withdraw the delegate approval from both vault ATAs — the counterpart `approve_trading`",
        "never had (SECURITY-AUDIT H-3).",
        "",
        "`approve_trading` grants u64::MAX, so until now a compromised market Asset PDA could",
        "drain the vault with no on-chain way to stop it short of a program upgrade — which,",
        "after the Squads handoff, is a proposal cycle run while the drain is in progress.",
        "",
        "Revoking is operator-or-owner for the same reason `rwa_market::set_active` is: taking",
        "the allowance away is the safe direction, and making it wait for a multisig defeats the",
        "point. Re-granting stays owner-only.",
        "Grant a market-maker venue a CAPPED allowance over this vault, per asset.",
        "",
        "The venue needs two things the market does not provide: release stock to a maker on",
        "creation, and pay cash to a maker on redemption. Neither can go through the delegate",
        "mechanism approve_trading uses, because an SPL token account has exactly ONE delegate and",
        "the Asset PDA already holds it. So the vault signs these transfers itself, bounded by",
        "this record.",
        "",
        "The allowance lives in its own PDA rather than on `Vault`, which is sized exactly",
        "(mint + owner + bump) with no reserved space — adding fields there would mean",
        "reallocating every vault already on chain. Per-venue is also the right shape: it mirrors",
        "the per-spender allowance on the EVM side, and two venues on one asset never share a",
        "budget.",
        "",
        "Absolute, not incremental, so revocation is a single call that cannot be gamed upward.",
        "Zero revokes.",
        "Revoke or restore a venue's ability to take on NEW obligations. Owner only.",
        "",
        "The twin of `VaultUpgradeable.setAuthorisedVenue`. Deliberately not part of",
        "`set_venue_allowance`: a budget and an authorisation are different statements, and",
        "conflating them meant the two chains disagreed about what the issuer's off switch does."
      ],
      "discriminator": [
        250,
        251,
        28,
        115,
        11,
        59,
        114,
        128
      ],
      "accounts": [
        {
          "name": "owner",
          "writable": true,
          "signer": true
        },
        {
          "name": "vault",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        },
        {
          "name": "venue"
        },
        {
          "name": "allowance",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  97,
                  108,
                  108,
                  111,
                  119,
                  97,
                  110,
                  99,
                  101
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              },
              {
                "kind": "account",
                "path": "venue"
              }
            ]
          }
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        }
      ],
      "args": [
        {
          "name": "revoked",
          "type": "bool"
        }
      ]
    },
    {
      "name": "sync_owner",
      "docs": [
        "Re-point `vault.owner` at the CURRENT `config.authority` (SECURITY-AUDIT M-1).",
        "",
        "`owner` is the only thing standing between the multisig and `owner_withdraw`, so a Squad",
        "migration that could not move it would strand every existing vault under the old one.",
        "The value comes from Config, never the caller, so this can only converge."
      ],
      "discriminator": [
        46,
        5,
        232,
        198,
        59,
        158,
        160,
        119
      ],
      "accounts": [
        {
          "name": "config",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  111,
                  110,
                  102,
                  105,
                  103
                ]
              }
            ]
          }
        },
        {
          "name": "signer",
          "signer": true
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "vault.mint",
                "account": "Vault"
              }
            ]
          }
        }
      ],
      "args": []
    }
  ],
  "accounts": [
    {
      "name": "Config",
      "discriminator": [
        155,
        12,
        170,
        224,
        30,
        250,
        204,
        130
      ]
    },
    {
      "name": "Vault",
      "discriminator": [
        211,
        8,
        232,
        43,
        2,
        152,
        117,
        119
      ]
    },
    {
      "name": "VenueAllowance",
      "discriminator": [
        91,
        148,
        10,
        78,
        228,
        123,
        45,
        64
      ]
    }
  ],
  "events": [
    {
      "name": "ConfigSet",
      "discriminator": [
        15,
        104,
        59,
        16,
        236,
        241,
        8,
        6
      ]
    },
    {
      "name": "MarketProgramSet",
      "discriminator": [
        145,
        81,
        151,
        169,
        54,
        177,
        83,
        40
      ]
    },
    {
      "name": "OwnerSynced",
      "discriminator": [
        5,
        52,
        178,
        203,
        234,
        173,
        4,
        213
      ]
    },
    {
      "name": "TradingRevoked",
      "discriminator": [
        233,
        222,
        118,
        65,
        11,
        59,
        67,
        137
      ]
    },
    {
      "name": "VaultCreated",
      "discriminator": [
        117,
        25,
        120,
        254,
        75,
        236,
        78,
        115
      ]
    },
    {
      "name": "VenueAllowanceSet",
      "discriminator": [
        48,
        48,
        99,
        242,
        146,
        235,
        11,
        164
      ]
    },
    {
      "name": "VenueDrew",
      "discriminator": [
        55,
        16,
        237,
        94,
        0,
        148,
        9,
        144
      ]
    }
  ],
  "errors": [
    {
      "code": 6000,
      "name": "Unauthorized",
      "msg": "caller is not the vault owner"
    },
    {
      "code": 6001,
      "name": "AllowanceExceeded",
      "msg": "draw exceeds the venue's remaining allowance"
    },
    {
      "code": 6002,
      "name": "AlreadyMigrated",
      "msg": "vault has already been migrated to the current layout"
    },
    {
      "code": 6003,
      "name": "VenueRevoked",
      "msg": "the venue's authorisation has been revoked; it may take on no new obligations"
    }
  ],
  "types": [
    {
      "name": "Config",
      "docs": [
        "Program-level authority. One per program, seeds [\"config\"].",
        "",
        "Exists because every per-asset `init` instruction used to accept an unconstrained `Signer`",
        "as \"admin\" and write it straight into the new account, making whoever called first the",
        "owner of a PDA our own flow would later fund. See C-1..C-5 in SECURITY-AUDIT.md."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "authority",
            "docs": [
              "Governing authority — the Squads vault PDA. Written into every per-asset account's",
              "admin/owner field, so a caller can never nominate itself."
            ],
            "type": "pubkey"
          },
          {
            "name": "operator",
            "docs": [
              "Operator hot key. May CREATE per-asset accounts and pay their rent, but never chooses",
              "who controls them."
            ],
            "type": "pubkey"
          },
          {
            "name": "bump",
            "type": "u8"
          }
        ]
      }
    },
    {
      "name": "ConfigSet",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "authority",
            "type": "pubkey"
          },
          {
            "name": "operator",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "MarketProgramSet",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "market_program",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "OwnerSynced",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "previous",
            "type": "pubkey"
          },
          {
            "name": "current",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "TradingRevoked",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "by",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "Vault",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "owner",
            "type": "pubkey"
          },
          {
            "name": "bump",
            "type": "u8"
          },
          {
            "name": "total_return_credit",
            "docs": [
              "Stock owed back to makers across ALL venues on this vault — the ring-fence floor.",
              "",
              "Per-venue `return_credit` on the allowance PDA cannot guard a withdrawal, because a",
              "withdrawal is not made in any venue's name and the vault cannot enumerate allowances.",
              "This is the number every path that releases stock has to respect, and it is the exact",
              "counterpart of VaultUpgradeable.totalReturnCredit on Base.",
              "",
              "Accounts created before this field existed are 73 bytes and must be grown by",
              "`migrate_vault` before they can be read. See that instruction."
            ],
            "type": "u64"
          },
          {
            "name": "market_program",
            "docs": [
              "The rwa_market deployment allowed to draw inventory for retail buys.",
              "",
              "Stored, never compiled in. `rwa_market` depends on this program, so depending back is a",
              "cycle cargo refuses — and a hardcoded id is a wire the compiler cannot check, which is",
              "the same mistake as a hardcoded venue id. Zero means no market is configured and",
              "`market_draw_stock` refuses outright, which fails CLOSED."
            ],
            "type": "pubkey"
          },
          {
            "name": "total_owed_payment",
            "docs": [
              "Cash a venue owes a maker but has not yet delivered — the payment-side ring-fence floor.",
              "",
              "The exact counterpart of `total_return_credit` on the stock side, and of",
              "VaultUpgradeable.totalOwedPayment on Base. A deferred payout leaves the cNGN sitting in",
              "this vault, and cash already spoken for must stop behaving like free cash: otherwise the",
              "next redemption's float includes money promised to the last one and the vault pays the",
              "same cNGN twice."
            ],
            "type": "u64"
          }
        ]
      }
    },
    {
      "name": "VaultCreated",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "owner",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "VenueAllowance",
      "docs": [
        "A venue's remaining budget against one vault. Seeds [\"venue_allowance\", mint, venue]."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "vault_mint",
            "type": "pubkey"
          },
          {
            "name": "venue",
            "type": "pubkey"
          },
          {
            "name": "stock_remaining",
            "docs": [
              "RWA smallest units the venue may still draw."
            ],
            "type": "u64"
          },
          {
            "name": "payout_remaining",
            "docs": [
              "Payout-token smallest units the venue may still draw."
            ],
            "type": "u64"
          },
          {
            "name": "return_credit",
            "docs": [
              "RWA units this vault owes BACK to the venue's makers.",
              "",
              "Separate from stock_remaining on purpose. That is a BUDGET and may be spent to zero or",
              "revoked; this is a DEBT, credited when a maker delivers stock into a redemption queue",
              "and consumed when that redemption is paid for. Returning what someone already delivered",
              "is not a grant, and funding it from the creation allowance made the maker's backstop",
              "depend on the issuer keeping that allowance topped up — which contradicts the single",
              "promise the backstop exists to make.",
              "",
              "Not settable by the owner: set_venue_allowance leaves it alone."
            ],
            "type": "u64"
          },
          {
            "name": "owed_payment",
            "docs": [
              "Payout-token units this vault owes a venue's makers for payouts already DECIDED.",
              "",
              "The cash twin of `return_credit`, and separate from `payout_remaining` for exactly the",
              "same reason: a budget may be lowered or revoked, a debt may not. The budget is charged",
              "when the payout is RECORDED (`credit_owed_payment`), and delivery draws this instead —",
              "so lowering the allowance afterwards cannot strand money the vault has already set",
              "aside, and two resolutions cannot each commit the same budget (R3-1)."
            ],
            "type": "u64"
          },
          {
            "name": "revoked",
            "docs": [
              "The issuer's OFF SWITCH, mirroring `VaultUpgradeable.isAuthorisedVenue` (R3-1).",
              "",
              "Revoking stops the venue taking on NEW obligations — `credit_return`, so no new",
              "redemption may be queued — and touches nothing it has already taken on. Both debts stay",
              "drawable, so a maker already in the queue is never stranded by it.",
              "",
              "Separate from zeroing the budgets, which is a different statement: a zero allowance",
              "means \"fund nothing more\", and a queued redemption then resolves to a stock return",
              "rather than cash. Revocation means \"take on nothing more\" and is the stronger of the two."
            ],
            "type": "bool"
          },
          {
            "name": "bump",
            "type": "u8"
          }
        ]
      }
    },
    {
      "name": "VenueAllowanceSet",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "venue",
            "type": "pubkey"
          },
          {
            "name": "stock",
            "type": "u64"
          },
          {
            "name": "payout",
            "type": "u64"
          }
        ]
      }
    },
    {
      "name": "VenueDrew",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "venue",
            "type": "pubkey"
          },
          {
            "name": "stock",
            "type": "u64"
          },
          {
            "name": "payout",
            "type": "u64"
          }
        ]
      }
    }
  ]
}