# Handoff: RN Multichain Proxy Probe — 2026-05-28

## Probe execution

Script: `backend/scripts/probe-rn-chains.ts` (commits `01b9ea0` → `4a85737`, backend 2.6.46 → 2.6.47)
Executed: 2026-05-28T15:57:33Z (final run after Base fix)

## Results summary

| Chain | Chain ID | Proxy Address | RPC | Reachable | Has Code | Call Valid | Status |
|-------|----------|---------------|-----|-----------|----------|------------|--------|
| BNB Smart Chain | 56 | `0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9` | publicnode | ✅ | ✅ | ✅ | **Verified** |
| Arbitrum One | 42161 | `0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9` | publicnode | ✅ | ✅ | ✅ | **Verified** |
| Ethereum Mainnet | 1 | `0x370DE27fdb7D1Ff1e1BaA7D11c5820a324Cf623C` | publicnode | ✅ | ✅ | ✅ | **Verified** |
| Polygon | 137 | `0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9` | publicnode | ✅ | ✅ | ✅ | **Verified** |
| Base | 8453 | `0x1892196E80C4c17ea5100Da765Ab48c1fE2Fb814` | publicnode | ✅ | ✅ | ✅ | **Verified** |

## Methodology

1. **Reachability**: `eth_blockNumber` against each chain's public RPC endpoint.
2. **Code presence**: `eth_getCode` at the candidate proxy address.
3. **Function validity**: `eth_call` with a dummy `transferFromWithReferenceAndFee` payload. A valid proxy reverts with an ERC-20/execution error (proving the selector is recognized). An invalid address would revert with "unknown function selector" or return empty.

## Key findings

- **BSC / Arbitrum / Polygon**: Canonical CREATE2 proxy `0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9` is deployed and responds correctly. ✅
- **Ethereum Mainnet**: v0.1.0 proxy `0x370DE27fdb7D1Ff1e1BaA7D11c5820a324Cf623C` is the official deployment per RN smart-contracts artifact. The canonical CREATE2 address is also deployed (v0.2.0-next) but the artifact marks it as an additional deployment. ✅
- **Base**: The canonical CREATE2 address has **no code** on Base. However, RN **does** support Base via a non-canonical deployment at `0x1892196E80C4c17ea5100Da765Ab48c1fE2Fb814` (per RN smart-contracts artifact v0.2.0, `packages/smart-contracts/src/lib/artifacts/ERC20FeeProxy/index.ts`). ✅

## Base proxy address hunt

Source: https://raw.githubusercontent.com/RequestNetwork/requestNetwork/master/packages/smart-contracts/src/lib/artifacts/ERC20FeeProxy/index.ts

```ts
base: {
  address: '0x1892196E80C4c17ea5100Da765Ab48c1fE2Fb814',
  creationBlockNumber: 10827274,
},
```

## Action taken

- Updated `supportedChains.json` with correct per-chain proxy addresses.
- Restored Base USDC/USDT entries to `tokens.json`.
- All 5 chains now active in the registry.

## AML scope note (for legal / compliance review)

The current AML implementation (Task #10, shipped in backend/frontend 2.6.47) performs **sanctions-only screening** via the Chainalysis Public Sanctions API. It checks whether a buyer's source wallet address appears on known sanctions lists (OFAC, UN, HMT, etc.). It does **not** perform full AML risk scoring — there is no transaction clustering, entity attribution, travel-rule monitoring, or behavioral risk scoring. Upgrading to comprehensive AML/KYT would require a paid Chainalysis KYT tier (or equivalent provider such as Elliptic, TRM Labs, or ComplyAdvantage), which runs ~$100K+/year for production volumes and requires an enterprise contract. The sanctions-only tier is free (5,000 requests per 5 minutes) and is the correct scope for a v1 compliance posture, but it should be explicitly described to regulators/customers as "sanctions screening" rather than "AML screening."

## Remaining work

- [ ] BSC USDT paid end-to-end probe (PRD §2 AC #3) — **pending human-in-the-loop**.
- [x] Mainnet USDT `approve(0)` reset verification (PRD §2 AC #4) — **VERIFIED via anvil fork test**.

## Human-blocked items (requires owner with wallet on dev)

These three items cannot be validated by automated tests alone. A human with a funded wallet on the dev environment must execute each probe before the corresponding feature is considered production-ready.

| # | Item | Precise next step | Blocking |
|---|---|---|---|
| 1 | **Task #7C — Live multi-seller divergent-destination probe** | Create a cart with seller-offers from ≥2 different sellers, complete checkout, verify RN creates 2 separate Payments with 2 distinct derived destination addresses, and both webhooks fire correctly. | Task #7 closure |
| 2 | **Task #8 — BSC USDT paid end-to-end probe** | On dev.amn.gg, complete a real BSC USDT pay-in through the in-house checkout (approve + `transferFromWithReferenceAndFee`), confirm webhook marks Payment `completed`, and BscScan shows the token transfer. | Multichain release gate |
| 3 | **Task #11 — Trezor signing dry-run** | Register a physical Trezor via `/api/trezor/register`, build a sweep tx via `POST /api/admin/actions/build-tx`, sign it on-device through the admin UI, broadcast via wagmi, and confirm `POST /api/admin/actions/confirm-tx` accepts the Trezor proof. | Trezor enforcement toggle |

## Mainnet USDT approve(0) reset — fork test verification

**Test:** `scripts/tenderly-usdt-reset-test.sh` (anvil fork of Ethereum mainnet)
**Date:** 2026-05-28

### Setup
- Forked mainnet at `https://ethereum-rpc.publicnode.com`
- Impersonated whale `0xF977814e90dA44bFA03b6295A0616a897441aceC`
- Transferred 100 USDT to test buyer `0x0000…dEaD`

### Transaction sequence

| Step | Description | Tx Hash |
|------|-------------|---------|
| 1 | Transfer USDT whale → buyer | `0x574440bc7aa2915ff8b5adddc9b083420c5e426894fe98d7c72196f7d8e37c22` |
| 2 | `approve(proxy, 50 USDT)` — quirk setup | `0x4dfef21e19e9fe17e7fb60ecefdce6f5a240e74de904f772c57ad3a3013454b8` |
| 3 | `approve(proxy, 0)` — reset | `0xf249a05db18753abf7625b44074b81939764c5a1590928d29aba0757ae5446b0` |
| 4 | `approve(proxy, 100 USDT)` — re-approve | `0xd27c1c382a20db754dd3d67efbb565016ad33c460be9fb7a09986589626aaef5` |
| 5 | `transferFromWithReferenceAndFee` — pay | `0xf7b44000fc11bcc1e832360acc9cbbfccd8be4c21f5940df00115ea7f2c4038a` |

### Results
- Allowance after partial approve: `50,000,000` ✅
- Allowance after reset: `0` ✅
- Allowance after full approve: `100,000,000` ✅
- Buyer balance decreased by exactly 100 USDT after payment ✅

### Verdict

**PRD §2 AC #4 status: VERIFIED** — The USDT-mainnet approve(0) reset flow executes correctly on a mainnet fork. All five transactions succeeded. The two-step approve pattern (reset → re-approve → pay) is validated end-to-end.
