Fix MCV2_Bond event ABIs: Mint/Burn not Minted/Burned#337
Conversation
The upstream MCV2_Bond.sol uses event names `Mint` and `Burn` (not `Minted`/`Burned`), with 6 params and 3 indexed (not 5 params and 2 indexed). The wrong signatures caused decodeEventLog to silently fail on every trade, resulting in zero rows in trade_history. Corrected: - Mint(address indexed token, address indexed user, address receiver, uint256 amountMinted, address indexed reserveToken, uint256 reserveAmount) - Burn(address indexed token, address indexed user, address receiver, uint256 amountBurned, address indexed reserveToken, uint256 refundAmount) Updated both the direct indexer and cron route to match. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
T2-2 ReviewNo blocking findings in this patch. I spot-checked the new Residual risk / test gap: this still needs an automated regression test with a captured Mint/Burn log fixture (or a mocked receipt) that proves |
realproject7
left a comment
There was a problem hiding this comment.
T2-1 Review — PR #337
ABI Corrections: APPROVE
Verified the corrected event signatures against MCV2_Bond.sol upstream:
event Mint(address indexed token, address indexed user, address receiver, uint256 amountMinted, address indexed reserveToken, uint256 reserveAmount);
event Burn(address indexed token, address indexed user, address receiver, uint256 amountBurned, address indexed reserveToken, uint256 refundAmount);The corrected ABIs in lib/contracts/abi.ts match exactly — event names, parameter names, types, indexed flags, and ordering are all correct. This fix resolves the root cause of trade_history being empty.
Issues Found
1. receiver field omitted from type assertions — LOW
Both consumers destructure decoded.args but neither includes receiver in the type assertion:
src/app/api/index/trade/route.ts:72-77:
const args = decoded.args as {
token: `0x${string}`;
amountMinted?: bigint;
amountBurned?: bigint;
reserveAmount?: bigint;
refundAmount?: bigint;
};src/app/api/cron/trade-history/route.ts:173-179:
const args = decoded.args as {
token: `0x${string}`;
user: `0x${string}`;
amountMinted?: bigint;
amountBurned?: bigint;
reserveAmount?: bigint;
refundAmount?: bigint;
};receiver is not accessed so this is functionally harmless — viem decodes all fields regardless of the type assertion. But the trade indexer route also omits user from its type assertion while the cron route includes it. Neither route stores the trader address (user) or receiver in the trade_history row. This is fine if the table schema doesn't have a trader_address column, but if trade attribution is wanted later, the data is available in the event and should be persisted. Not blocking.
2. Hardcoded 18 decimals in price calculation — EXISTING CONCERN (not introduced by this PR)
Both routes compute pricePerToken using formatUnits(*, 18). This is the same hardcoded-decimals pattern flagged in the #320 audit (B10). Not a regression from this PR, but noting for completeness since this code was touched.
3. No SDK ABI update — CONCERN
The SDK (packages/sdk/src/abi.ts) is not updated with these corrected events. The SDK's mcv2BondAbi currently doesn't include Mint/Burn events at all, so there's no immediate breakage. But if SDK consumers add trade event decoding later, they'll need these events. Worth tracking but not blocking this PR.
Verdict
APPROVE — The ABI corrections are verified against upstream source and the consumer code changes are consistent. The fix is minimal and correctly scoped. Ship it.
Summary
The MCV2_Bond event ABIs were completely wrong — wrong event names AND wrong signatures. This caused
decodeEventLogto silently fail on every trade, resulting in zero rows intrade_history.What was wrong:
Minted/Burned— actual names areMint/BurntokenAmountvsamountMinted/amountBurned)Verified against: MCV2_Bond.sol upstream source
Files changed
lib/contracts/abi.ts— corrected event definitionssrc/app/api/index/trade/route.ts— updated event name checks and arg destructuringsrc/app/api/cron/trade-history/route.ts— same updates for cronTest plan
POST /api/index/tradereturns{ indexed: 1 }(not 0)trade_historySupabase table