Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .changeset/apriori-explorer-tier.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@themoss/protocol-apriori": minor
---

Move the aprMON ABI to the explorer tier (ADR 0007). The EIP-1967 implementation
is now verified on MonadScan, so `src/abis/apriori.ts` is the full implementation
ABI fetched from the explorer and committed as typed `as const`, generated by
`update:abis` from the `scripts/abis.ts` source table. A keyed
`test-online/abi-explorer.test.ts` cross-checks the committed ABI against the
explorer-verified implementation with `compareDeployedAbi` and an offline
`test/abis.test.ts` asserts the committed module is exact `renderAbiModule`
output. The exported `AprMonAbi` now carries the full artifact, including the
`viewRedeemRequest` and `getUserRequestData` view helpers.
58 changes: 35 additions & 23 deletions packages/protocols/apriori/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,41 @@ withdrawal queue:
Canonical deployment source: [aPriori's official integration docs](https://apriori-docs.gitbook.io/apriori-docs/aprmon/smart-contract-integration),
which publish the mainnet address and the exact function/event signatures.

## ABI provenance (ADR 0007, vendored tier)

When this adapter landed the implementation contract was not explorer-verified,
so no explorer artifact existed to fetch or compare. The ABI in
`src/abis/apriori.ts` is vendored verbatim from the official docs, restricted to
entries whose signatures are machine-verifiable, and the derivation is
test-enforced rather than asserted. The implementation is verified on MonadScan
since 2026-09-05 and its explorer ABI agrees with every vendored signature;
moving the package to the explorer tier with a keyed `compareDeployedAbi`
cross-check is tracked in [#197](https://github.com/nishuzumi/moss/issues/197).

- `abis.json` records the proxy/implementation pair.
- `test-online/abi-explorer.test.ts` (keyless, RPC-only) verifies on chain that
the proxy's EIP-1967 slot still resolves to the recorded implementation, that
both addresses have deployed bytecode, that **every** vendored function
selector and event topic hash recomputed from the artifact appears in the
implementation bytecode, that on-chain `name`/`symbol`/`decimals` match the
exported `APRMON_*` constants, and that `convertToShares`/`convertToAssets`
round-trip at a sane exchange rate.
- An aPriori upgrade flips the linkage test red, forcing human re-verification
of the vendored ABI. If aPriori verifies the implementation, this package
should switch to the keyed `fetchAbi` + `compareDeployedAbi` explorer
cross-check used by `@themoss/protocol-kuru`.
## ABI provenance (ADR 0007, explorer tier)

The implementation is verified on MonadScan (contract `aprMON`, compiler
v0.8.28, exact bytecode match), so `src/abis/apriori.ts` is the full
implementation ABI fetched from the explorer and committed as typed `as const`,
generated by `renderAbiModule` and never hand-edited. This is the explorer tier
of ADR 0007, above the vendored tier the package used when the implementation
had no verified source. The full artifact also carries the `viewRedeemRequest`
and `getUserRequestData` view helpers the curated vendored ABI never included.

Refresh the ABI from the repository root with:

```bash
MONADSCAN_API_KEY=... pnpm --filter @themoss/protocol-apriori update:abis
```

- `scripts/abis.ts` records the source table (implementation address, export
name, module file); `update:abis` re-fetches and renders from it.
- `abis.json` pins the expected proxy/implementation pair and the reviewed
`allowedExplorerOnly` exceptions (none today).
- `test/abis.test.ts` (offline) asserts the source table fetches the implementation
`abis.json` pins, and re-derives the committed module from its own embedded ABI
and retrieval date, so drift from `renderAbiModule`'s canonical rendering or from
the recorded address fails closed. ABI content itself is defended by the keyed
cross-check below and, for the three decoded events, by the real-log Receipt test.
- `test-online/abi-explorer.test.ts` (keyed, needs `MONADSCAN_API_KEY`) verifies
on chain that the proxy's EIP-1967 slot still resolves to the recorded
implementation, that the proxy has deployed bytecode, that on-chain
`name`/`symbol`/`decimals` match the exported `APRMON_*` constants, that
`convertToShares`/`convertToAssets` round-trip at a sane exchange rate and that
the committed ABI is semantically identical to the ABI of the
explorer-verified implementation (`compareDeployedAbi`). A missing key fails
the suite rather than skipping.
- An aPriori upgrade flips the linkage and cross-check red, forcing human
re-verification of the ABI.

## Receipts

Expand Down
3 changes: 2 additions & 1 deletion packages/protocols/apriori/abis.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"aprMon": {
"proxy": "0x0c65A0BC65a5D819235B71F554D210D3F80E0852",
"implementation": "0x7D2F8dc5a67CA1911bb1A2429552CDf507d106F2"
"implementation": "0x7D2F8dc5a67CA1911bb1A2429552CDf507d106F2",
"allowedExplorerOnly": []
}
}
4 changes: 3 additions & 1 deletion packages/protocols/apriori/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"build": "tsup src/index.ts --format esm --dts --sourcemap --clean --target es2022",
"typecheck": "tsc --noEmit",
"test": "vitest run",
"test:abi:online": "vitest run --config vitest.online.config.ts"
"test:abi:online": "vitest run --config vitest.online.config.ts",
"update:abis": "tsx scripts/update-abis.ts"
},
"dependencies": {
"@themoss/core": "workspace:*",
Expand All @@ -28,6 +29,7 @@
"@themoss/abi-tools": "workspace:*",
"@themoss/simulator": "workspace:*",
"@themoss/system": "workspace:*",
"tsx": "^4.19.0",
"tsup": "^8.5.1",
"typescript": "~5.9.0",
"vitest": "^3.2.6"
Expand Down
7 changes: 7 additions & 0 deletions packages/protocols/apriori/scripts/abis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const SOURCES = [
{
address: "0x7D2F8dc5a67CA1911bb1A2429552CDf507d106F2",
exportName: "AprMon",
file: "apriori.ts",
},
] as const;
18 changes: 18 additions & 0 deletions packages/protocols/apriori/scripts/update-abis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { writeFileSync } from "node:fs";
import { fetchAbi, renderAbiModule } from "@themoss/abi-tools";
import { SOURCES } from "./abis.js";

const key = process.env.MONADSCAN_API_KEY;
if (!key) {
throw new Error(
"MONADSCAN_API_KEY is not set; create one at https://info.monadscan.com/myapikey/ and export it.",
);
}

const abisDir = new URL("../src/abis/", import.meta.url);
const retrievedAt = new Date();
for (const { exportName, file, address } of SOURCES) {
const abi = await fetchAbi(address, key);
writeFileSync(new URL(file, abisDir), renderAbiModule({ exportName, address, abi, retrievedAt }));
console.log(`src/abis/${file}: ${abi.length} ABI entries from ${address}`);
}
Loading
Loading