[CL-MEGA-W] fix(token): floor burn-deposit кредита до целых центов (BE-DEFI-04) #932

Closed
andrei wants to merge 0 commits from feature/claude-mega-audit-w-20260629 into master
Owner

Что сделано

  • Мега-аудит EuropaTech (промпт «МЕГА-АУДИТ», 8-finder × per-finding adversarial-verify; GitNexus + Serena; дельта 1148 коммитов master с прошлого аудита). Итог: 1 LIVE LOW, 0 Critical/High новых. 7/8 finders — clean, подтверждено живым чтением кода.
  • Фикс BE-DEFI-04 (api/src/services/token.query.service.ts, depositFromChain): кредит on-chain EURT-burn считался через roundEur (round-half-up). Заменён на weiToEurDecimal(amountWei) — floor, точная bigint-арифметика (без float, без half-up), parity с уже закалённым vault/operations.ts (BE-DEFI-01). Sub-cent-only burns floor → 0.00 → отклоняются guard'ом amountEur <= 0.
  • Тесты (test-first, RED→GREEN): новый регресс на sub-cent over-credit + скорректированы 2 ассерта под floor (cap 5000049999.99, fractional 1.999 EURT 21.99).
  • Docs: отчёт docs/vault/reviews/mega-audit-w-2026-06-29.md + обновлён docs/vault/AUDIT-STATUS.md.

Зачем

roundEur округлял вверх на половине → burn 0.005 EURT (5e15 wei) кредитил 0.01 EUR, майня до ~0.005 EUR/tx небеспеченного off-chain coinBalance. Нарушение инварианта MiCA EMT 1:1 backing («EUR-кредит ≤ on-chain сожжённое»). Attacker-tunable, систематично (уникальный txHash обходит @unique); capается <0.005 EUR/tx + требует жечь реальный EURT + газ → LOW.

План тестирования

  • npx vitest run src/services/__tests__/token.query.service.test.ts → 54/54 PASS
  • npx eslint ... --max-warnings 0 → 0 · npx tsc --noEmit → 0
  • pre-push tsc + build + prerender — зелёный
  • code-review (mandatory, solo-dev 103.1): APPROVE, 0 Crit/High, 2 LOW адресованы (консолидация импорта + safety-комментарий)
  • prod health (read-only): europa-tech.org 200 · api/api/health ok

Где могу ошибаться

  • Number(weiToEurDecimal(...)): 2-decimal строка → точно до cap 50k (cents ≤ 2^53; проверено тестом 49999.99).
  • Поведенческое изменение: burn'ы с sub-cent-хвостом теперь floor (на ≤0.009 EUR меньше) — это и есть корректное поведение (прежний half-up = over-credit).
  • Затронут только off-chain credit-путь burn-deposit; on-chain не трогается; blast radius мал (controller→service).
## Что сделано - **Мега-аудит EuropaTech** (промпт «МЕГА-АУДИТ», 8-finder × per-finding adversarial-verify; GitNexus + Serena; дельта 1148 коммитов master с прошлого аудита). Итог: **1 LIVE LOW, 0 Critical/High новых**. 7/8 finders — clean, подтверждено живым чтением кода. - **Фикс BE-DEFI-04** (`api/src/services/token.query.service.ts`, `depositFromChain`): кредит on-chain EURT-burn считался через `roundEur` (round-half-up). Заменён на `weiToEurDecimal(amountWei)` — floor, точная bigint-арифметика (без float, без half-up), parity с уже закалённым `vault/operations.ts` (BE-DEFI-01). Sub-cent-only burns floor → 0.00 → отклоняются guard'ом `amountEur <= 0`. - **Тесты** (test-first, RED→GREEN): новый регресс на sub-cent over-credit + скорректированы 2 ассерта под floor (cap `50000`→`49999.99`, fractional 1.999 EURT `2`→`1.99`). - **Docs**: отчёт `docs/vault/reviews/mega-audit-w-2026-06-29.md` + обновлён `docs/vault/AUDIT-STATUS.md`. ## Зачем `roundEur` округлял вверх на половине → burn 0.005 EURT (5e15 wei) кредитил 0.01 EUR, майня до ~0.005 EUR/tx небеспеченного off-chain `coinBalance`. Нарушение инварианта MiCA EMT 1:1 backing («EUR-кредит ≤ on-chain сожжённое»). Attacker-tunable, систематично (уникальный txHash обходит `@unique`); capается <0.005 EUR/tx + требует жечь реальный EURT + газ → LOW. ## План тестирования - `npx vitest run src/services/__tests__/token.query.service.test.ts` → 54/54 PASS - `npx eslint ... --max-warnings 0` → 0 · `npx tsc --noEmit` → 0 - pre-push tsc + build + prerender — зелёный - code-review (mandatory, solo-dev 103.1): APPROVE, 0 Crit/High, 2 LOW адресованы (консолидация импорта + safety-комментарий) - prod health (read-only): europa-tech.org 200 · api/api/health ok ## Где могу ошибаться - `Number(weiToEurDecimal(...))`: 2-decimal строка → точно до cap 50k (cents ≤ 2^53; проверено тестом 49999.99). - Поведенческое изменение: burn'ы с sub-cent-хвостом теперь floor (на ≤0.009 EUR меньше) — это и есть корректное поведение (прежний half-up = over-credit). - Затронут только off-chain credit-путь burn-deposit; on-chain не трогается; blast radius мал (controller→service).
andrei force-pushed feature/claude-mega-audit-w-20260629 from 8227df4e7e
Some checks failed
CI / API (pull_request) Has been cancelled
CI / App (pull_request) Has been cancelled
CI / Contracts (pull_request) Has been cancelled
CI / Telegram Mini App (pull_request) Has been cancelled
CI / Python SDK (pull_request) Has been cancelled
CI / Secrets Scan (pull_request) Has been cancelled
CI / Prisma Migrate Gate (pull_request) Has been cancelled
PR Janitor / janitor (pull_request) Has been cancelled
Deploy EuropaTech / SEO Health Gate (push) Has been skipped
Deploy EuropaTech / Deploy API to Hetzner (push) Has been skipped
Deploy EuropaTech / Deploy Static to Hetzner (push) Has been skipped
CI / API (push) Waiting to run
CI / App (push) Waiting to run
CI / Contracts (push) Waiting to run
CI / Telegram Mini App (push) Waiting to run
CI / Python SDK (push) Waiting to run
CI / Secrets Scan (push) Waiting to run
CI / Prisma Migrate Gate (push) Waiting to run
Deploy EuropaTech / Production Release Gate (push) Waiting to run
to 19756dee2e
Some checks failed
CI / Python SDK (pull_request) Has been cancelled
CI / Secrets Scan (pull_request) Has been cancelled
CI / Prisma Migrate Gate (pull_request) Has been cancelled
PR Janitor / janitor (pull_request) Has been cancelled
CI / App (pull_request) Has been cancelled
CI / Telegram Mini App (pull_request) Has been cancelled
CI / API (pull_request) Has been cancelled
CI / Contracts (pull_request) Has been cancelled
2026-06-29 14:00:43 +00:00
Compare

⚠️ Конфликт с master — ветку нужно перебазировать вручную. Изменения в master перекрыли затронутые строки.

<!-- janitor-conflict --> ⚠️ Конфликт с master — ветку нужно перебазировать вручную. Изменения в master перекрыли затронутые строки.
[CL-MEGA-W] fix(token): align token query service imports and comments with master
Some checks failed
CI / API (pull_request) Has been cancelled
CI / App (pull_request) Has been cancelled
CI / Contracts (pull_request) Has been cancelled
CI / Telegram Mini App (pull_request) Has been cancelled
CI / Python SDK (pull_request) Has been cancelled
CI / Secrets Scan (pull_request) Has been cancelled
CI / Prisma Migrate Gate (pull_request) Has been cancelled
PR Janitor / janitor (pull_request) Has been cancelled
d254ad40f4
andrei force-pushed feature/claude-mega-audit-w-20260629 from d254ad40f4
Some checks failed
CI / API (pull_request) Has been cancelled
CI / App (pull_request) Has been cancelled
CI / Contracts (pull_request) Has been cancelled
CI / Telegram Mini App (pull_request) Has been cancelled
CI / Python SDK (pull_request) Has been cancelled
CI / Secrets Scan (pull_request) Has been cancelled
CI / Prisma Migrate Gate (pull_request) Has been cancelled
PR Janitor / janitor (pull_request) Has been cancelled
to 6e19134f7b
Some checks failed
CI / App (pull_request) Has been cancelled
CI / Contracts (pull_request) Has been cancelled
CI / Telegram Mini App (pull_request) Has been cancelled
CI / Python SDK (pull_request) Has been cancelled
CI / Secrets Scan (pull_request) Has been cancelled
CI / Prisma Migrate Gate (pull_request) Has been cancelled
PR Janitor / janitor (pull_request) Has been cancelled
React Doctor / React Doctor / App (pull_request) Successful in 3m6s
CI / API (pull_request) Has been cancelled
2026-06-29 15:11:44 +00:00
Compare
andrei force-pushed feature/claude-mega-audit-w-20260629 from 6e19134f7b
Some checks failed
CI / App (pull_request) Has been cancelled
CI / Contracts (pull_request) Has been cancelled
CI / Telegram Mini App (pull_request) Has been cancelled
CI / Python SDK (pull_request) Has been cancelled
CI / Secrets Scan (pull_request) Has been cancelled
CI / Prisma Migrate Gate (pull_request) Has been cancelled
PR Janitor / janitor (pull_request) Has been cancelled
React Doctor / React Doctor / App (pull_request) Successful in 3m6s
CI / API (pull_request) Has been cancelled
to 49a1f6e9af
Some checks are pending
CI / API (pull_request) Successful in 16m10s
CI / App (pull_request) Successful in 17m14s
CI / Secrets Scan (pull_request) Successful in 13s
PR Janitor / janitor (pull_request) Successful in 8s
CI / Contracts (pull_request) Successful in 2m34s
CI / Telegram Mini App (pull_request) Successful in 1m30s
CI / Python SDK (pull_request) Successful in 29s
CI / Prisma Migrate Gate (pull_request) Successful in 1m25s
Deploy EuropaTech / SEO Health Gate (push) Has been skipped
Deploy EuropaTech / Deploy API to Hetzner (push) Has been skipped
Deploy EuropaTech / Deploy Static to Hetzner (push) Has been skipped
CI / API (push) Waiting to run
CI / App (push) Waiting to run
CI / Contracts (push) Waiting to run
CI / Telegram Mini App (push) Waiting to run
CI / Python SDK (push) Waiting to run
CI / Secrets Scan (push) Waiting to run
CI / Prisma Migrate Gate (push) Waiting to run
Deploy EuropaTech / Production Release Gate (push) Waiting to run
2026-06-29 15:36:17 +00:00
Compare
andrei closed this pull request 2026-06-29 16:22:56 +00:00
Some checks are pending
CI / API (pull_request) Successful in 16m10s
CI / App (pull_request) Successful in 17m14s
CI / Secrets Scan (pull_request) Successful in 13s
PR Janitor / janitor (pull_request) Successful in 8s
CI / Contracts (pull_request) Successful in 2m34s
CI / Telegram Mini App (pull_request) Successful in 1m30s
CI / Python SDK (pull_request) Successful in 29s
CI / Prisma Migrate Gate (pull_request) Successful in 1m25s
Deploy EuropaTech / SEO Health Gate (push) Has been skipped
Deploy EuropaTech / Deploy API to Hetzner (push) Has been skipped
Deploy EuropaTech / Deploy Static to Hetzner (push) Has been skipped
CI / API (push) Waiting to run
CI / App (push) Waiting to run
CI / Contracts (push) Waiting to run
CI / Telegram Mini App (push) Waiting to run
CI / Python SDK (push) Waiting to run
CI / Secrets Scan (push) Waiting to run
CI / Prisma Migrate Gate (push) Waiting to run
Deploy EuropaTech / Production Release Gate (push) Waiting to run

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
europa-tech-srl/europatech!932
No description provided.