Repository navigation
feat(contracts): emit named events from every state-changing entrypoint - #71
Merged
codemagician1949 merged 1 commit intoAug 25, 2026
Conversation
Off-chain indexers had no reliable signal for several state transitions:
one entrypoint emitted nothing at all, and the events that did exist carried
too little to reconstruct what happened.
process_repayment emitted nothing
---------------------------------
`repayment-waterfall::process_repayment` moved reserve capital via a
cross-contract call and emitted no event, so a repayment was invisible to
any index. It now emits `("repaid",)` with `(amount, timestamp)`.
The publish is placed *after* the `apply_reserve_delta` call, not before: if
that call traps the whole invocation reverts, and an event should never be
claimed for a transfer that did not happen.
verify_invoice carried no verifier
----------------------------------
It emitted `("inv_ver",)` with just the invoice id. An audit trail is only
ever asked two questions — who, and when — and neither was recoverable. The
id now moves to a topic, so an indexer can subscribe per invoice instead of
decoding every payload, and the payload carries `(verifier, timestamp)`.
assign_invoice lost the previous owner
--------------------------------------
It emitted the pool as a topic and the id as data. The previous owner was
nowhere, and after the assignment it is gone from storage too — the write
overwrites it — so the event was the only place it could have survived. Now
captured before the write and emitted as `(previous_owner, pool, timestamp)`.
join_pool could not be reconciled
---------------------------------
It emitted only `shares`. Shares are minted at the prevailing NAV, so
without the amount paid and the NAV used there is no way to check the mint
was priced correctly, or to rebuild a lender's cost basis from the event
stream. Now `(amount, shares, nav, total_shares)`, with the running total so
pool size is trackable without a state read.
Not included here: `create_invoice`. That entrypoint and its event are the
subject of IntensifierLab#13, and are left entirely to that PR so the two do not overlap.
Wasm size warning
-----------------
`pool_manager.wasm` was already the closest to the 64KB CI limit at 64,262
bytes. The richer `join_pool` event takes it to 64,848 — still passing, but
headroom is now 688 bytes. The next addition to that contract is likely to
break the size gate, and it is worth deciding deliberately whether to raise
the limit or split the contract before that happens.
Verification
------------
- `cargo test --workspace` — all tests passing, 6 of them new
- release wasm builds clean; every contract under the 64KB limit
(governance 30,005 · invoice_registry 47,755 · pool_manager 64,848 ·
repayment_waterfall 44,714)
The new tests drive each entrypoint to its success path and compare the
emitted event whole — topic and payload together — rather than picking out
fields, plus a negative case asserting a rejected repayment emits nothing,
since a phantom credit in an index is worse than a missing one.
Closes IntensifierLab#4
Contributor
|
Nice job @oluwagbemigaphilip |
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Off-chain indexers had no reliable signal for several state transitions:
one entrypoint emitted nothing at all, and the events that did exist carried
too little to reconstruct what happened.
process_repayment emitted nothing
repayment-waterfall::process_repaymentmoved reserve capital via across-contract call and emitted no event, so a repayment was invisible to
any index. It now emits
("repaid",)with(amount, timestamp).The publish is placed after the
apply_reserve_deltacall, not before: ifthat call traps the whole invocation reverts, and an event should never be
claimed for a transfer that did not happen.
verify_invoice carried no verifier
It emitted
("inv_ver",)with just the invoice id. An audit trail is onlyever asked two questions — who, and when — and neither was recoverable. The
id now moves to a topic, so an indexer can subscribe per invoice instead of
decoding every payload, and the payload carries
(verifier, timestamp).assign_invoice lost the previous owner
It emitted the pool as a topic and the id as data. The previous owner was
nowhere, and after the assignment it is gone from storage too — the write
overwrites it — so the event was the only place it could have survived. Now
captured before the write and emitted as
(previous_owner, pool, timestamp).join_pool could not be reconciled
It emitted only
shares. Shares are minted at the prevailing NAV, sowithout the amount paid and the NAV used there is no way to check the mint
was priced correctly, or to rebuild a lender's cost basis from the event
stream. Now
(amount, shares, nav, total_shares), with the running total sopool size is trackable without a state read.
Not included here:
create_invoice. That entrypoint and its event are thesubject of #13, and are left entirely to that PR so the two do not overlap.
Wasm size warning
pool_manager.wasmwas already the closest to the 64KB CI limit at 64,262bytes. The richer
join_poolevent takes it to 64,848 — still passing, butheadroom is now 688 bytes. The next addition to that contract is likely to
break the size gate, and it is worth deciding deliberately whether to raise
the limit or split the contract before that happens.
Verification
cargo test --workspace— all tests passing, 6 of them new(governance 30,005 · invoice_registry 47,755 · pool_manager 64,848 ·
repayment_waterfall 44,714)
The new tests drive each entrypoint to its success path and compare the
emitted event whole — topic and payload together — rather than picking out
fields, plus a negative case asserting a rejected repayment emits nothing,
since a phantom credit in an index is worse than a missing one.
Closes #4