Skip to content

feat: u256 to felt scaling procedure#2331

Merged
partylikeits1983 merged 36 commits intoagglayer-newfrom
ajl-u256-felt-downscale-procedure
Feb 18, 2026
Merged

feat: u256 to felt scaling procedure#2331
partylikeits1983 merged 36 commits intoagglayer-newfrom
ajl-u256-felt-downscale-procedure

Conversation

@partylikeits1983
Copy link
Contributor

@partylikeits1983 partylikeits1983 commented Jan 23, 2026

This PR adds functionality which checks that a given Felt value is the correctly scaled amount from a u256 value. This is to ensure that a u256 asset amount is correctly scaled to a Felt value on Miden.

Follow up to this PR is to add the scaled Felt amount as NoteStorage to the CLAIM note.

Resolves point 2.2 here: #2237
Builds on top of: #2270
Context: #2011 (comment)

@partylikeits1983 partylikeits1983 self-assigned this Jan 23, 2026
@partylikeits1983 partylikeits1983 added agglayer PRs or issues related to AggLayer bridging integration no changelog This PR does not require an entry in the `CHANGELOG.md` file labels Jan 23, 2026
@partylikeits1983 partylikeits1983 marked this pull request as ready for review January 23, 2026 19:13
@partylikeits1983 partylikeits1983 marked this pull request as draft January 23, 2026 22:15
@partylikeits1983 partylikeits1983 removed the request for review from bobbinth January 23, 2026 22:15
@partylikeits1983 partylikeits1983 marked this pull request as ready for review January 23, 2026 22:21
@partylikeits1983
Copy link
Contributor Author

#2336 Shows how the scale_u256_to_native_amount procedure which this PR adds is used in the context of the CLAIM note consumption.

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Thank you! Looks good. I left some more comments inline.

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you! I left some more comments inline - but I think we are pretty close.

Comment on lines 247 to 253
/// # Errors
/// - [`EthAmountError::ScaleTooLarge`] if scale_exp > 18
/// - [`EthAmountError::ScaledValueNotCanonicalFelt`] if the result doesn't fit in a canonical
/// Felt
/// - [`EthAmountError::ScaledValueDoesNotFitU64`] if the result doesn't fit in a u64
/// - [`EthAmountError::ScaledValueExceedsMaxFungibleAmount`] if the scaled value exceeds the
/// maximum fungible token amount
Copy link
Contributor

Choose a reason for hiding this comment

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

Related to the above, we can probably delete line 249 as if we get a valid token amount, we know for sure it fits into Felt.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed line 249

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you!

@mmagician mmagician added the pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority label Feb 9, 2026
@partylikeits1983 partylikeits1983 changed the base branch from agglayer to agglayer-new February 12, 2026 08:36
@partylikeits1983 partylikeits1983 changed the base branch from agglayer-new to agglayer February 12, 2026 08:42
@partylikeits1983 partylikeits1983 force-pushed the ajl-u256-felt-downscale-procedure branch from db9825d to 3ea2737 Compare February 13, 2026 08:40
@partylikeits1983 partylikeits1983 changed the base branch from agglayer to agglayer-new February 13, 2026 08:40
@partylikeits1983
Copy link
Contributor Author

I rebased to agglayer-new branch while maintaining existing old commits. Rebasing to agglayer-new required a force push.

Addressing comments from @mmagician from here: #2435

Copy link
Collaborator

Choose a reason for hiding this comment

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

FYI: in #2401, the underlying repr of EthAmount changes to just contain bytes, and many of the helper methods are removed (some can be added back if needed, but wanted to keep the interface minimal when they weren't needed).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Especially after #2413, we know that the way CLAIM note is constructed will be correct in terms of endianness.
I believe the main changes there w.r.t. amounts are:

let amount = EthAmount::new(hex_to_bytes(&self.amount).expect("valid amount hex")); // this should be refactored to take a decimal string, not hex string
let amount_felts: Vec<Felt> = amount.to_elements();

where to_elements() returns the field elements in BE-limb order, but LE-byte order 😱

It appears that verify_u256_to_native_amount_conversion operates on the reverse on both fronts (LE-limb order but BE-byte order?) but please correct me if I'm wrong.

So what I would suggest is coupling the changes in this PR to changes from the linked PR above.
Then we could have a bridgin-in test where:

  1. we know the leaf data hashes correctly to the leaf value (related to this since the amount is part of the leaf data)
  2. proof data verifies against GER (not directly related, but the computation of leaf value in 1. matters for the verification)
  3. There is an output note created with the correct amount (the real safety check)

@mmagician
Copy link
Collaborator

I think there are two changes needed on my side (a follow-up to #2413):

  • the test vectors should generate a uint string with amounts, not a hex string
  • the amount & destination address should be extracted to stack before validate_claim, saved to memory locals, and passed on stack "as arguments" to the build_p2id_output_note procedure

After which I think the best course of actions is either:

  1. Pick the relevant changes from the PR tower related to how EthAmount changed, and adapt the fn/tests to ensure that passing amount.to_elements()'s output to verify_u256_to_native_amount_conversion produces the correct result. This option might be a little quicker, but won't let us test the whole flow (since CLAIM doesn't hash nor validate its data correctly in agglayer-new yet), and eventually some merge resolution still needs to happen (but could be either here or in feat(AggLayer claim e2e #4): e2e bridge-in flow with real bridge data #2413)
  2. Rebase this on top of / merge with feat(AggLayer claim e2e #4): e2e bridge-in flow with real bridge data #2413 (actually, the upcoming follow up which I just mentioned at the top of this comment), which ensures full compatibility, but we'll need to deal with multiple merge conflicts now.

I have a strong preference for 2: conflicts need to be dealt with anyways eventually, and we'll be sure of compatibility right away.

@partylikeits1983 partylikeits1983 changed the base branch from agglayer-new to mmagician-real-claim-followups February 16, 2026 08:21
Base automatically changed from mmagician-real-claim-followups to agglayer-new February 16, 2026 09:02
@partylikeits1983
Copy link
Contributor Author

Merged latest changes from agglayer-new branch and cherry picked @mmagician's commit which added the reverse_limbs_and_change_byte_endianness procedure.

Copy link
Collaborator

@mmagician mmagician left a comment

Choose a reason for hiding this comment

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

two comments about the changes left, once these are addressed let's merge.

Also a note for the future regarding cherry-picking, but I think we'll be able to work around this later

Comment on lines +258 to +262

# reverse limbs and byte endianness
exec.reverse_limbs_and_change_byte_endianness
# => [x0, x1, x2, x3, x4, x5, x6, x7, scale_exp, y]

Copy link
Collaborator

Choose a reason for hiding this comment

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

Currently the changes in 30f2416 include both the procedure itself, which was cherry-picked, but also other changes that incorporate that procedure into the rest of the code.
I'm not sure if the rebase will work smoothly afterwards because of this. Ideally, these would have been two separate commits

@partylikeits1983 partylikeits1983 merged commit 0ff8f8f into agglayer-new Feb 18, 2026
15 checks passed
@partylikeits1983 partylikeits1983 deleted the ajl-u256-felt-downscale-procedure branch February 18, 2026 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agglayer PRs or issues related to AggLayer bridging integration no changelog This PR does not require an entry in the `CHANGELOG.md` file pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants