Skip to content

Emit InitEvent on contract init - #81

Open
ebubeb683-ship-it wants to merge 1 commit into
clevercon-protocol:mainfrom
ebubeb683-ship-it:main
Open

Emit InitEvent on contract init#81
ebubeb683-ship-it wants to merge 1 commit into
clevercon-protocol:mainfrom
ebubeb683-ship-it:main

Conversation

@ebubeb683-ship-it

@ebubeb683-ship-it ebubeb683-ship-it commented Jul 25, 2026

Copy link
Copy Markdown

Closes #63
What does this PR do?

  • Introduces a new InitEvent contract event to capture the admin address and USDC SAC address during contract initialization.
  • Emits InitEvent at the end of CleverVault::init, ensuring the event is part of the durable event stream that indexers and explorers consume.
  • Updates unit tests (test_init) to verify that InitEvent is emitted with the correct fields.

Why is this needed?

The original init function only logged the admin address, which does not appear in the durable event stream. Downstream tooling (indexers, explorers, analytics) rely on events to detect contract deployment and retrieve initial state without extra RPC calls. Adding InitEvent provides a deterministic, observable way to capture the admin and asset information at initialization.

Verification

  • cargo test passes, confirming the new event is emitted and stored correctly.
  • All changes have been committed and pushed to the main branch (branch now tracks origin/main).

Additional Notes

  • No other parts of the codebase were altered.
  • The commit message used for this change is: “Emit InitEvent on contract init”.
    Please review and merge.
    4:54 PM

Summary by CodeRabbit

  • New Features

    • Initialization now emits an event containing the administrator and USDC SAC addresses, improving visibility into contract setup.
  • Bug Fixes

    • Prevented repeated initialization attempts from emitting additional events.
  • Tests

    • Expanded event verification for initialization, pausing, unpausing, and administrator updates.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The agent vault now defines and emits an InitEvent containing initialization addresses. Tests verify its payload, ensure failed duplicate initialization emits no event, and update event-count expectations for subsequent operations.

Changes

Agent vault initialization event

Layer / File(s) Summary
Define and publish initialization event
contracts/agent-vault/src/lib.rs
Defines the public InitEvent contract event and publishes it after initial storage setup and USDC SAC whitelisting.
Validate initialization event behavior
contracts/agent-vault/src/tests.rs
Checks the initialization event payload, confirms duplicate initialization adds no event, and updates later event-count assertions.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Initializer
  participant AgentVault
  participant SorobanEvents
  Initializer->>AgentVault: init(admin, usdc_sac)
  AgentVault->>SorobanEvents: publish InitEvent(admin, usdc_sac)
Loading

Possibly related PRs

Suggested reviewers: dopezapha, yerimahoftimes, naninu123

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes emitting InitEvent during contract initialization.
Linked Issues check ✅ Passed The changes add InitEvent, publish it in init, and tighten tests for first and second initialization behavior.
Out of Scope Changes check ✅ Passed All changes are directly related to emitting and testing InitEvent on contract initialization.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

Warning

⚠️ This pull request shows signs of AI-generated slop (description_diff_mismatch). It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@contracts/agent-vault/src/tests.rs`:
- Around line 51-63: Update the InitEvent assertions in the event verification
test to expect the static topic init_event and validate the complete payload
containing both test_env.admin and test_env.usdc_sac. Keep the existing event
count and contract ID checks, but replace the current event.1-only assertion
with checks matching the emitted event’s topic and data shape.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b79efdfd-6c66-41cf-9882-3e4555126cc0

📥 Commits

Reviewing files that changed from the base of the PR and between 7827994 and 6764b83.

📒 Files selected for processing (2)
  • contracts/agent-vault/src/lib.rs
  • contracts/agent-vault/src/tests.rs

Comment on lines +51 to +63
// Verify InitEvent emission
let events = test_env.env.events().all();
assert_eq!(events.events().len(), 1);
let event = events.events().last().unwrap();
assert_eq!(event.0, test_env.contract_id);
assert_eq!(
event.1,
(
Symbol::new(&test_env.env, "InitEvent"),
test_env.admin.clone()
)
.into_val(&test_env.env)
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files contracts/agent-vault/src/tests.rs contracts/agent-vault/src/*.rs

echo
echo "== event-related symbols =="
rg -n "contractevent|InitEvent|init_event|usdc_sac|InitEvent" contracts/agent-vault/src -S

echo
echo "== tests.rs excerpt =="
nl -ba contracts/agent-vault/src/tests.rs | sed -n '1,120p'

echo
echo "== candidate source excerpts =="
for f in $(git ls-files contracts/agent-vault/src/*.rs | grep -v 'tests.rs'); do
  echo "--- $f ---"
  nl -ba "$f" | sed -n '1,220p'
done

Repository: clevercon-protocol/clevercon

Length of output: 29168


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

for path, start, end in [
    ("contracts/agent-vault/src/lib.rs", 20, 40),
    ("contracts/agent-vault/src/tests.rs", 45, 70),
]:
    print(f"--- {path}:{start}-{end} ---")
    text = Path(path).read_text().splitlines()
    for i in range(start, min(end, len(text)) + 1):
        print(f"{i:4}: {text[i-1]}")
PY

Repository: clevercon-protocol/clevercon

Length of output: 1707


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
path = Path("contracts/agent-vault/src/lib.rs")
text = path.read_text().splitlines()
for i in range(286, 322):
    if i <= len(text):
        print(f"{i:4}: {text[i-1]}")
PY

Repository: clevercon-protocol/clevercon

Length of output: 1745


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

for path in ["contracts/agent-vault/Cargo.toml", "Cargo.toml"]:
    p = Path(path)
    if p.exists():
        print(f"--- {path} ---")
        for i, line in enumerate(p.read_text().splitlines(), 1):
            if "soroban-sdk" in line or "edition" in line or "version" in line:
                print(f"{i:4}: {line}")
PY

echo
rg -n "events\\(\\)\\.all\\(|publish\\(&env\\)|Symbol::new\\(&.*init_event|Symbol::new\\(&.*InitEvent" contracts/agent-vault/src -S

Repository: clevercon-protocol/clevercon

Length of output: 1651


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

path = Path("contracts/agent-vault/src/tests.rs")
text = path.read_text().splitlines()

for start, end in [(1560, 1610), (2055, 2090), (88, 105)]:
    print(f"--- {path}:{start}-{end} ---")
    for i in range(start, min(end, len(text)) + 1):
        print(f"{i:4}: {text[i-1]}")
    print()
PY

Repository: clevercon-protocol/clevercon

Length of output: 3942


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
text = Path("contracts/agent-vault/src/tests.rs").read_text().splitlines()
for i, line in enumerate(text, 1):
    if "into_val(&" in line or "event.1" in line or "events.events()" in line:
        print(f"{i:4}: {line}")
PY

Repository: clevercon-protocol/clevercon

Length of output: 479


🌐 Web query:

Soroban SDK 25.3.0 contractevent lower_snake_case static topic struct name data payload topic fields

💡 Result:

In the Soroban SDK, the #[contractevent] attribute macro is used to define contract events [1][2]. When using this macro on a struct, the SDK handles the event's topics and data payload according to the following conventions: Default Static Topics and Naming: By default, an event defined with #[contractevent] includes a single static topic, which is the name of the struct converted to lower_snake_case [1][3][4]. This fixed topic is automatically positioned as the first item in the event's topic list, appearing before any dynamic topics defined in the struct [1][5]. Customizing Static Topics: You can override or customize these static topics using the topics parameter within the macro: - Custom Static Topic: By providing a list of strings, such as #[contractevent(topics = ["my_contract", "an_event"])], you replace the default struct-name-based topic with your custom list [1]. - Multiple/Empty Static Topics: It is possible to specify multiple static topics (up to two) or even provide an empty list (topics = []) if no static topics are desired [3][4]. Dynamic Topics and Data Payload: - Dynamic Topics: Fields within the struct marked with the #[topic] attribute are included as dynamic topics in the event's topic list [1][3]. These follow the static topics [1]. - Data Payload: Fields within the struct that are not marked with #[topic] are automatically placed in the event's data payload section [1][3]. Example Structure: #[contractevent] pub struct MyEvent { #[topic] pub my_dynamic_topic: u32, // Becomes a dynamic topic pub my_event_data: u32, // Becomes part of the data payload } In this example, the resulting topics would be: 1. "my_event" (the struct name in lower_snake_case) 2. The value of my_dynamic_topic [1]

Citations:


Match the emitted event shape and assert the payload. InitEvent uses init_event as the static topic, and usdc_sac is part of the data payload; checking only event.1 misses a wrong SAC address.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@contracts/agent-vault/src/tests.rs` around lines 51 - 63, Update the
InitEvent assertions in the event verification test to expect the static topic
init_event and validate the complete payload containing both test_env.admin and
test_env.usdc_sac. Keep the existing event count and contract ID checks, but
replace the current event.1-only assertion with checks matching the emitted
event’s topic and data shape.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task]: Emit an InitEvent when CleverVault is initialized

1 participant