Skip to content

feat: Derive fiat order sourceAmount from on-chain tx data#8694

Open
OGPoyraz wants to merge 5 commits intomainfrom
ogp/fiat-order-txhash-implementation
Open

feat: Derive fiat order sourceAmount from on-chain tx data#8694
OGPoyraz wants to merge 5 commits intomainfrom
ogp/fiat-order-txhash-implementation

Conversation

@OGPoyraz
Copy link
Copy Markdown
Member

@OGPoyraz OGPoyraz commented May 5, 2026

Explanation

Currently, the fiat submit flow derives sourceAmountRaw from order.cryptoAmount - a human-readable value reported by the on-ramp provider. This value may not precisely reflect what was actually received on-chain.

This PR reads the actual transferred amount from the completed on-chain transaction (order.txHash) instead. For native tokens, the amount is taken from tx.value. For ERC-20 tokens, the amount is decoded from the transfer(address,uint256) call data. If the on-chain read fails or the transaction hash is missing, the existing order.cryptoAmount derivation is used as a fallback.

The implementation introduces:

  • getTransferredAmountFromTxHash - a generic utility in utils/transaction-receipt.ts that reads transferred amounts from any on-chain transaction (native or ERC-20). Takes explicit chainId and tokenAddress params for reusability.
  • resolveSourceAmountRaw - a fiat-strategy-specific function in strategy/fiat/utils.ts that orchestrates the on-chain read with order.cryptoAmount fallback.
  • getRawSourceAmountFromOrderCryptoAmount - the existing decimal-shift conversion, moved from fiat-submit.ts to strategy/fiat/utils.ts and renamed for clarity.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Changes how fiat submission computes sourceAmountRaw by reading on-chain transaction data via RPC, which can impact relay quoting/submission correctness and adds new failure modes around provider reads and ERC-20 calldata decoding.

Overview
Fiat submit now derives the relay sourceAmountRaw from the completed order’s on-chain transaction (order.txHash) when available, falling back to decimal-shifting order.cryptoAmount if the read fails or yields no amount.

This introduces a reusable getTransferredAmountFromTxHash utility to read native tx.value or decode ERC-20 transfer(address,uint256) calldata, refactors the prior cryptoAmount conversion into getRawSourceAmountFromOrderCryptoAmount, and updates/expands unit tests plus the package changelog accordingly.

Reviewed by Cursor Bugbot for commit 0a7e13c. Bugbot is set up for automated code reviews on this repo. Configure here.

@OGPoyraz OGPoyraz requested review from a team as code owners May 5, 2026 11:40
@OGPoyraz OGPoyraz changed the title feat: derive fiat order source amount from on-chain tx data feat: Derive fiat order sourceAmount from on-chain tx data May 5, 2026
Comment thread packages/transaction-pay-controller/src/strategy/fiat/utils.ts
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0a7e13c. Configure here.


const decoded = erc20Interface.decodeFunctionData('transfer', tx.data);

return positiveOrUndefined(decoded._value.toString());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ERC-20 path ignores tokenAddress, no tx.to verification

Medium Severity

getTransferredAmountFromTxHash accepts a tokenAddress parameter but, for ERC-20 tokens, never verifies that tx.to matches this address. It only uses tokenAddress to pick the native-vs-ERC-20 path. If the order.txHash points to a transfer call on a different ERC-20 contract, the function silently decodes and returns that unrelated amount. Because this is described as a generic reusable utility, callers may reasonably assume tokenAddress scopes the result to the intended token.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0a7e13c. Configure here.

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.

1 participant