fix(sdk-coin-flrp): compute Flare C-chain import fee from real gas usage - #9385
fix(sdk-coin-flrp): compute Flare C-chain import fee from real gas usage#9385ArunBala-Bitgo wants to merge 1 commit into
Conversation
|
@claude review this PR |
|
Claude finished @ArunBala-Bitgo's task —— View job Code Review for Flare C-chain Import Fee FixTodo List:
Overall AssessmentThis PR successfully addresses a critical issue in Flare C-chain atomic import transactions where underestimated gas fees were causing broadcast failures. The implementation is well-architected, maintains backward compatibility, and includes comprehensive test coverage. ✅ Strengths1. Excellent Problem Analysis & Solution Design
2. Robust Implementation Architecture
3. Comprehensive Test CoverageThe new test suite (
4. Backward Compatibility
🔍 Detailed Code AnalysisInterface Changes (
|
f3f0716 to
27ca6a4
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates the Flare (FLR/coston2) C-chain atomic import transaction builder to support deriving the import fee from actual gas usage (including FlareJS’s AtomicTxBaseCost) by introducing an opt-in base-fee-driven build path, while keeping the legacy literal fee() behavior for backward compatibility.
Changes:
- Added a
baseFee()builder input to compute import fees from real gas usage viaevm.newImportTxFromBaseFee(...), including a 10% base-fee padding buffer. - Updated import builder validation/build logic to accept
baseFeeas an alternative to a literalfee. - Added unit tests covering the base-fee-driven path and expected fee characteristics.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| modules/sdk-coin-flrp/src/lib/ImportInCTxBuilder.ts | Adds base-fee-derived import fee computation via FlareJS and applies base-fee padding. |
| modules/sdk-coin-flrp/src/lib/atomicTransactionBuilder.ts | Introduces a baseFee() setter on atomic transaction builders. |
| modules/sdk-coin-flrp/src/lib/iface.ts | Extends fee shape to include an optional baseFee field for C-chain imports. |
| modules/sdk-coin-flrp/test/unit/lib/importInCTxBuilder.ts | Adds unit tests for the base-fee-driven import builder behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
modules/sdk-coin-flrp/src/lib/ImportInCTxBuilder.ts:207
- In the baseFee path, the computed fee is only validated as > 0. This is weaker than the legacy fixed-fee path, which requires
totalUtxoAmount > fee(ensuring some amount is actually imported). As written, a tx where the computed fee consumes the entire UTXO amount (outputs sum to 0) would pass validation and setfeeto the full input amount.
const innerImportTx = importTx.getTx() as evmSerial.ImportTx;
const totalOutputAmount = innerImportTx.Outs.reduce((sum, out) => sum + out.amount.value(), BigInt(0));
const computedFee = totalUtxoAmount - totalOutputAmount;
if (computedFee <= BigInt(0)) {
throw new BuildTransactionError(
modules/sdk-coin-flrp/test/unit/lib/importInCTxBuilder.ts:238
- This comment is misleading:
baseFeeWeiis already in wei-per-gas, but the note says "gwei-equivalent" even though the literal value is500n(wei). Updating the comment avoids confusion about what unit the builder expects.
const baseFeeWei = 500n; // gwei-equivalent base fee used in the reported failure
const underpricedGasEstimate = 5700n; // naive/legacy gas estimate missing AtomicTxBaseCost
const underpricedFee = baseFeeWei * underpricedGasEstimate;
21585d6 to
ce1aa8a
Compare
Import-to-C-chain transactions built a fee from a caller-supplied literal amount, bypassing flarejs's actual gas accounting (which includes the ~10,000 AtomicTxBaseCost). When the caller priced the import using a naive gas estimate, the resulting fee was too low and the network rejected the transaction with insufficient funds, independent of transfer amount. Add an opt-in baseFee() builder method that computes the fee via newImportTxFromBaseFee (mirroring the export builder's existing pattern), with a 10% padding buffer to absorb base-fee volatility between signing and broadcast. The legacy fee() literal-amount path is unchanged for backward compatibility. Ticket: CECHO-1821
ce1aa8a to
7c4cc6c
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
modules/sdk-coin-flrp/src/lib/ImportInCTxBuilder.ts:144
- The error message here only mentions
fee, but the builder now also acceptsbaseFee. When neither is provided, the message should reflect the new valid option to reduce confusion for callers.
if (!hasFee && !hasBaseFee) {
throw new BuildTransactionError('fee is required');
}
modules/sdk-coin-flrp/src/lib/ImportInCTxBuilder.ts:209
- After computing the fee from
baseFee, the transaction ends up with bothfee(now computed) andbaseFeeset. That contradicts the earlier mutual-exclusivity validation and can confuse downstream consumers/serialization. Consider clearingbaseFeeonce the final fee is derived to preserve the invariant.
this.transaction._fee.fee = computedFee.toString();
Summary
evm.newImportTx(fee), treating the caller-supplied fee as a literal amount and never accounting for the ~10,000 gasAtomicTxBaseCostthat flarejs's gas estimator applies internally.baseFee()builder method that instead callsevm.newImportTxFromBaseFee(...), letting flarejs compute the real gas cost (includingAtomicTxBaseCost) from the actual tx, and applies a 10% padding buffer on the supplied base fee to absorb volatility between signing and broadcast. This mirrors the pattern the export builder (ExportInCTxBuilder) already uses vianewExportTxFromBaseFee.fee()path is untouched for backward compatibility with existing (on-chain verified) test vectors.Test plan
npx mocha --exclude test/unit/flrp.ts 'test/unit/**/*.ts'inmodules/sdk-coin-flrp— 275 passingtsc --noEmitandeslintclean (no new warnings)Ticket: CECHO-1821
🤖 Generated with Claude Code