Skip to content

[PLEX-2731] - Cre forwarder#87

Open
ilija42 wants to merge 23 commits into
mainfrom
cre-forwarder
Open

[PLEX-2731] - Cre forwarder#87
ilija42 wants to merge 23 commits into
mainfrom
cre-forwarder

Conversation

@ilija42
Copy link
Copy Markdown
Collaborator

@ilija42 ilija42 commented Apr 28, 2026

No description provided.

@ilija42 ilija42 changed the title Cre forwarder [PLEX-2731] - Cre forwarder Apr 28, 2026
@ilija42 ilija42 changed the title [PLEX-2731] - Cre forwarder [PLEX-2731] - Cre forwarder Reference Draft Apr 29, 2026
@ilija42 ilija42 changed the title [PLEX-2731] - Cre forwarder Reference Draft [PLEX-2731] - Cre forwarder Draft May 26, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 27, 2026

Soroban Contract Test Coverage

93.21% line coverage — 18033 / 19347 lines hit

Metric Hit Total Coverage
Lines 18033 19347 93.21%
Functions 1186 1484 79.92%
Regions 33579 35771 93.87%

Per-Contract Breakdown

Contract Lines (Hit / Total) Line Cov Funcs (Hit / Total) Func Cov
other 18033 / 19347 93.2% 1186 / 1484 79.9%
Full file-level coverage report
Filename                                                 Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover    Branches   Missed Branches     Cover
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ccip-ramp-registry/src/lib.rs                                188                75    60.11%           8                 3    62.50%         104                41    60.58%           0                 0         -
ccip-ramp-registry/src/test.rs                               214                 0   100.00%           5                 0   100.00%         128                 0   100.00%           0                 0         -
ccip-ramp-registry/src/types.rs                               83                11    86.75%          17                 6    64.71%          83                11    86.75%           0                 0         -
ccvs/committee-verifier/src/lib.rs                           438                43    90.18%          22                 2    90.91%         294                 8    97.28%           0                 0         -
ccvs/committee-verifier/src/test.rs                         1363                28    97.95%          49                 2    95.92%         621                15    97.58%           0                 0         -
ccvs/committee-verifier/src/types.rs                          15                 6    60.00%           4                 3    25.00%          12                 5    58.33%           0                 0         -
ccvs/versioned-verifier-resolver/src/lib.rs                  287                21    92.68%          14                 1    92.86%         162                 4    97.53%           0                 0         -
ccvs/versioned-verifier-resolver/src/test.rs                 680                 9    98.68%          20                 0   100.00%         359                 3    99.16%           0                 0         -
ccvs/versioned-verifier-resolver/src/types.rs                 89                 6    93.26%          16                 4    75.00%          83                 4    95.18%           0                 0         -
common/authorization/src/allowlist.rs                        167                51    69.46%          12                 4    66.67%         110                40    63.64%           0                 0         -
common/authorization/src/lib.rs                              426                27    93.66%          16                 0   100.00%         277                16    94.22%           0                 0         -
common/authorization/src/ownable.rs                          102                13    87.25%           9                 1    88.89%          62                 6    90.32%           0                 0         -
common/authorization/src/test.rs                            1195                 0   100.00%          57                 0   100.00%         462                 0   100.00%           0                 0         -
common/guard/src/initializable.rs                             30                 1    96.67%           4                 0   100.00%          22                 1    95.45%           0                 0         -
common/guard/src/lib.rs                                       32                 1    96.88%           4                 0   100.00%          22                 0   100.00%           0                 0         -
common/guard/src/test.rs                                     101                 0   100.00%           8                 0   100.00%          47                 0   100.00%           0                 0         -
common/helpers/src/curse_checkable.rs                        103                24    76.70%           6                 1    83.33%          56                12    78.57%           0                 0         -
common/helpers/src/map_updater.rs                             94                15    84.04%           7                 3    57.14%          39                 8    79.49%           0                 0         -
common/helpers/src/soroban_invoke.rs                         204                 4    98.04%           8                 0   100.00%          81                 0   100.00%           0                 0         -
common/interfaces/src/ccip_receiver.rs                         8                 8     0.00%           8                 8     0.00%           8                 8     0.00%           0                 0         -
common/interfaces/src/committee_verifier.rs                   10                10     0.00%          10                10     0.00%          10                10     0.00%           0                 0         -
common/interfaces/src/fee_quoter.rs                           17                17     0.00%          17                17     0.00%          17                17     0.00%           0                 0         -
common/interfaces/src/offramp.rs                              11                11     0.00%          11                11     0.00%          11                11     0.00%           0                 0         -
common/interfaces/src/onramp.rs                                9                 9     0.00%           9                 9     0.00%           9                 9     0.00%           0                 0         -
common/interfaces/src/ramp_registry.rs                         5                 5     0.00%           5                 5     0.00%           5                 5     0.00%           0                 0         -
common/interfaces/src/rmn_proxy.rs                             6                 6     0.00%           6                 6     0.00%           6                 6     0.00%           0                 0         -
common/interfaces/src/router.rs                                9                 9     0.00%           9                 9     0.00%           9                 9     0.00%           0                 0         -
common/interfaces/src/siloed_lock_release_pool.rs             21                21     0.00%          21                21     0.00%          21                21     0.00%           0                 0         -
common/interfaces/src/token_admin_registry.rs                  8                 8     0.00%           8                 8     0.00%           8                 8     0.00%           0                 0         -
common/interfaces/src/token_lock_box.rs                        6                 6     0.00%           6                 6     0.00%           6                 6     0.00%           0                 0         -
common/interfaces/src/token_pool.rs                           11                11     0.00%          11                11     0.00%          11                11     0.00%           0                 0         -
common/interfaces/src/versioned_verifier_resolver.rs          10                10     0.00%          10                10     0.00%          10                10     0.00%           0                 0         -
common/message/src/lib.rs                                    586                41    93.00%          28                 4    85.71%         298                 9    96.98%           0                 0         -
common/message/src/test.rs                                   641                 2    99.69%          28                 0   100.00%         323                 0   100.00%           0                 0         -
common/pool/src/decimals.rs                                  109                10    90.83%           6                 0   100.00%          76                 3    96.05%           0                 0         -
common/pool/src/finality_codec.rs                             52                 1    98.08%           3                 0   100.00%          41                 0   100.00%           0                 0         -
common/pool/src/lib.rs                                       460                31    93.26%          32                 1    96.88%         409                26    93.64%           0                 0         -
common/pool/src/rate_limit.rs                                180                 7    96.11%           9                 0   100.00%         145                 3    97.93%           0                 0         -
common/pool/src/types.rs                                      20                14    30.00%          16                14    12.50%          30                14    53.33%           0                 0         -
common/verifier/src/signatures.rs                            293                18    93.86%          10                 2    80.00%         192                11    94.27%           0                 0         -
cre/src/lib.rs                                               610                20    96.72%          34                 0   100.00%         405                 8    98.02%           0                 0         -
cre/src/test.rs                                             3019                12    99.60%         119                 3    97.48%        1233                11    99.11%           0                 0         -
cre/src/types.rs                                               5                 5     0.00%           5                 5     0.00%           5                 5     0.00%           0                 0         -
fee-quoter/src/lib.rs                                        771               164    78.73%          20                 3    85.00%         527               100    81.02%           0                 0         -
fee-quoter/src/test.rs                                       861                 0   100.00%          17                 0   100.00%         427                 0   100.00%           0                 0         -
fee-quoter/src/types.rs                                       13                13     0.00%          13                13     0.00%          13                13     0.00%           0                 0         -
mcms/src/abi_encoding.rs                                     216                 5    97.69%          10                 0   100.00%          98                 2    97.96%           0                 0         -
mcms/src/constants.rs                                         10                 0   100.00%           2                 0   100.00%           6                 0   100.00%           0                 0         -
mcms/src/crypto.rs                                           202                 3    98.51%           7                 0   100.00%         109                 2    98.17%           0                 0         -
mcms/src/error.rs                                              8                 4    50.00%           1                 0   100.00%           8                 4    50.00%           0                 0         -
mcms/src/lib.rs                                              713                52    92.71%          20                 0   100.00%         483                24    95.03%           0                 0         -
mcms/src/test.rs                                            2057                18    99.12%          55                 0   100.00%         987                 2    99.80%           0                 0         -
mcms/src/types.rs                                             10                10     0.00%          10                10     0.00%          10                10     0.00%           0                 0         -
offramp/src/lib.rs                                           729               400    45.13%          23                 8    65.22%         473               224    52.64%           0                 0         -
offramp/src/test.rs                                          890                 0   100.00%          28                 0   100.00%         363                 0   100.00%           0                 0         -
offramp/src/types.rs                                          21                 9    57.14%           6                 5    16.67%          17                 7    58.82%           0                 0         -
onramp/src/lib.rs                                           1181               149    87.38%          27                 2    92.59%         739                61    91.75%           0                 0         -
onramp/src/test.rs                                          1591                 4    99.75%          37                 0   100.00%         708                 4    99.44%           0                 0         -
onramp/src/types.rs                                           23                 9    60.87%           6                 5    16.67%          19                 7    63.16%           0                 0         -
pools/burn-mint-pool/src/lib.rs                              390               107    72.56%          28                 9    67.86%         282                55    80.50%           0                 0         -
pools/burn-mint-pool/src/test.rs                            2671                24    99.10%          56                 5    91.07%        1744                55    96.85%           0                 0         -
pools/lock-release-pool/src/lib.rs                           404               100    75.25%          28                 8    71.43%         288                48    83.33%           0                 0         -
pools/lock-release-pool/src/test.rs                         2330                24    98.97%          55                 5    90.91%        1524                55    96.39%           0                 0         -
pools/siloed-lock-release-pool/src/lib.rs                    556               196    64.75%          38                17    55.26%         384               123    67.97%           0                 0         -
pools/siloed-lock-release-pool/src/test.rs                  1303                12    99.08%          38                 2    94.74%         695                18    97.41%           0                 0         -
pools/token-lock-box/src/lib.rs                              197                17    91.37%          13                 1    92.31%         113                 2    98.23%           0                 0         -
pools/token-lock-box/src/test.rs                             257                 0   100.00%           7                 0   100.00%          73                 0   100.00%           0                 0         -
registry/src/lib.rs                                            8                 0   100.00%           1                 0   100.00%           3                 0   100.00%           0                 0         -
registry/src/test.rs                                          27                 0   100.00%           1                 0   100.00%          11                 0   100.00%           0                 0         -
rmn_proxy/src/lib.rs                                          66                12    81.82%           5                 1    80.00%          34                 3    91.18%           0                 0         -
rmn_proxy/src/test.rs                                        279                 0   100.00%          11                 0   100.00%          91                 0   100.00%           0                 0         -
rmn_remote/src/lib.rs                                        302                26    91.39%          16                 1    93.75%         171                10    94.15%           0                 0         -
rmn_remote/src/test.rs                                       393                 0   100.00%          14                 0   100.00%         133                 0   100.00%           0                 0         -
router/src/lib.rs                                            593                87    85.33%          18                 1    94.44%         374                43    88.50%           0                 0         -
router/src/test.rs                                          1186                 0   100.00%          29                 0   100.00%         497                 0   100.00%           0                 0         -
router/src/test_panic_receiver.rs                              5                 0   100.00%           2                 0   100.00%           5                 0   100.00%           0                 0         -
router/src/types.rs                                            3                 3     0.00%           3                 3     0.00%           3                 3     0.00%           0                 0         -
timelock/src/error.rs                                          6                 2    66.67%           1                 0   100.00%           6                 2    66.67%           0                 0         -
timelock/src/lib.rs                                          649                46    92.91%          32                 2    93.75%         393                18    95.42%           0                 0         -
timelock/src/roles.rs                                        141                10    92.91%           6                 0   100.00%          76                 7    90.79%           0                 0         -
timelock/src/storage.rs                                      115                15    86.96%          12                 1    91.67%          68                 7    89.71%           0                 0         -
timelock/src/test.rs                                        1479                16    98.92%          37                 0   100.00%         531                 1    99.81%           0                 0         -
timelock/src/types.rs                                          3                 3     0.00%           3                 3     0.00%           3                 3     0.00%           0                 0         -
token-admin-registry/src/lib.rs                              368                23    93.75%          18                 1    94.44%         257                 4    98.44%           0                 0         -
token-admin-registry/src/test.rs                             825                 0   100.00%          21                 0   100.00%         287                 0   100.00%           0                 0         -
token-admin-registry/src/types.rs                              2                 2     0.00%           2                 2     0.00%           2                 2     0.00%           0                 0         -
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TOTAL                                                      35771              2192    93.87%        1484               298    79.92%       19347              1314    93.21%           0                 0         -```

</details>

> Commit `ecfbb2cb` | [Full CI run](https://github.com/smartcontractkit/chainlink-stellar/actions/runs/26850218724)

<!-- Sticky Pull Request Commentcontract-coverage -->

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 27, 2026

Integration Test Coverage (excl. Token Pool)

total:														(statements)				4.5%

Full coverage report

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 27, 2026

Integration Test Coverage (Token Pool)

total:														(statements)				2.6%

Full coverage report

@ilija42 ilija42 changed the title [PLEX-2731] - Cre forwarder Draft [PLEX-2731] - Cre forwarder Jun 2, 2026
@ilija42 ilija42 marked this pull request as ready for review June 2, 2026 21:52
@ilija42 ilija42 requested a review from Copilot June 2, 2026 21:55
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new Soroban smart contract crate (contracts/cre) implementing a “KeystoneForwarder” with ownership, forwarder registry, config management, signature verification, receiver dispatch, and transmission tracking for CRE report forwarding.

Changes:

  • Introduces the KeystoneForwarder contract, storage schema, and event types.
  • Adds an extensive Rust test suite covering initialization, config lifecycle, signature validation, replay rules, and receiver behavior.
  • Registers the new crate in the workspace (and lockfile) and adds a local Makefile for build/test.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
contracts/cre/src/lib.rs Core contract implementation: ownership/initialization guards, config + forwarder registry, report validation + signature verification, receiver dispatch + transmission tracking
contracts/cre/src/types.rs Contract storage/data model types (config, transmissions, storage keys, state enums)
contracts/cre/src/events.rs Contract event definitions for forwarder/config/report processing
contracts/cre/src/test.rs Comprehensive end-to-end and negative-path tests, plus crypto/test fixtures and mock receivers
contracts/cre/Cargo.toml New crate manifest and dependencies/dev-dependencies
contracts/cre/Makefile Local build/test/fmt targets for the new contract crate
Cargo.toml Adds contracts/cre to the workspace members
Cargo.lock Adds lock entries for the new crate and dev-deps

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread contracts/cre/src/lib.rs
Comment on lines +578 to +583
fn receiver_contract_id_bytes(env: &Env, receiver: &Address) -> Bytes {
match receiver.to_payload() {
Some(AddressPayload::ContractIdHash(hash)) => Bytes::from(hash),
_ => panic_with_error!(env, Error::InvalidReceiver),
}
}
Comment thread contracts/cre/src/lib.rs
Comment on lines +163 to +172
if f == 0 {
panic_with_error!(&env, Error::FaultToleranceMustBePositive);
}
if signers.len() > MAX_ORACLES {
panic_with_error!(&env, Error::ExcessSigners);
}
// BFT bound: need ≥ 3f + 1 signers configured to tolerate f faulty.
if signers.len() < f * 3 + 1 {
panic_with_error!(&env, Error::InsufficientSigners);
}
Comment thread contracts/cre/Cargo.toml
soroban-sdk = { workspace = true, features = ["testutils", "hazmat-address"] }
k256 = { version = "0.13", features = ["ecdsa"] }
sha3 = "0.10"
hex = "0.4"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nitpick: could be useful to move those to workspace deps so all contracts can use the same version, we'd need to do the same in CCIP contracts for things like sha3

Comment thread contracts/cre/src/lib.rs
// Storage TTL constants (ledger counts; 1 ledger ≈ 5 s on Mainnet).
// TODO adjust
const BUMP_FOR_60_DAYS: u32 = 1_036_800; // ~60 days
const BUMP_AFTER_30_DAYS: u32 = 518_400; // ~30 days
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I recommend making this configurable using instance storage

Comment thread contracts/cre/src/lib.rs Outdated
_ => unreachable!("unexpected CCIPError variant from Ownable/Initializable"),
}
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nitpick: moving this into its own file could be helpful

Comment thread contracts/cre/src/lib.rs Outdated
<KeystoneForwarder as Ownable>::require_owner(env)?;
env.storage()
.instance()
.extend_ttl(BUMP_AFTER_30_DAYS, BUMP_FOR_60_DAYS);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

instance storage does not require extending the TTL as it lives as long as the contract itself

Comment thread contracts/cre/src/lib.rs Outdated
Comment on lines +369 to +372
fn ensure_initialized(env: &Env) {
<KeystoneForwarder as Initializable>::require_initialized(env)
.unwrap_or_else(|_| panic_with_error!(env, Error::Uninitialized));
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This helper can be made into a one liner with the following change:

Suggested change
fn ensure_initialized(env: &Env) {
<KeystoneForwarder as Initializable>::require_initialized(env)
.unwrap_or_else(|_| panic_with_error!(env, Error::Uninitialized));
}
fn ensure_initialized(env: &Env) -> Result<(), Error> {
<KeystoneForwarder as Initializable>::require_initialized(env).map_err(|e| e.into())
}

Subsequent uses of the method could be as follows:

fn assert_owner(env: &Env) -> Result<(), Error> {
    ensure_initialized(env)?; // the `?` would take care of the panic
    //....
}

Comment thread contracts/cre/src/lib.rs Outdated
metadata: raw_report.slice(FORWARDER_METADATA_LENGTH..METADATA_LENGTH),
payload: raw_report.slice(METADATA_LENGTH..raw_report.len()),
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could be cleaner to move this into an impl of the ParsedReport type which you'd call with something like:

ParsedReport::From(...)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

That impl would then be extended to include the config_id() method as well

Comment thread contracts/cre/src/lib.rs

// ─────────────────────────────────────────────────────────────────────────────
// Signature verification
// ─────────────────────────────────────────────────────────────────────────────
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's a trait in common that might be helpful here called SignatureQuorum, I'm not sure if it's exactly what you need but could save you from writing the signature verification code here as well

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

Code coverage report:

Top package main cre-forwarder diff
github.com/smartcontractkit/chainlink-stellar/ccv 29.13% 29.13% +0.00%
github.com/smartcontractkit/chainlink-stellar/cmd 0.00% 0.00% +0.00%
github.com/smartcontractkit/chainlink-stellar/deployment 45.80% 45.80% +0.00%
github.com/smartcontractkit/chainlink-stellar/relayer 6.36% 6.36% +0.00%
github.com/smartcontractkit/chainlink-stellar/tests 0.00% 0.00% +0.00%

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.

3 participants