Repository navigation
Conversation
The DBC IDL is the audited 0.2.2 release (program commit 82054df): PoolConfig gains version and transferFeeFlag, createConfig2 takes an optional TransferFeeParameters, and the ExceededInputAmount and InvalidFeeClaimer errors are new. The DAMM v2 IDL and the cp_amm.so fixture are cp_amm 0.2.5. The dynamic_bonding_curve.so fixture is the same build the IDL was generated from. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds the transfer fee math (epoch fees, included and excluded amounts, the zero-fee rule) and reworks the swap quote so exact-in, partial-fill and exact-out follow the program's order of operations, including the referral split on exact-out and the ExceededInputAmount check on partial fills. Fee schedulers use the program's Q64 pow. Amounts are checked against the u64 and u128 bounds the program enforces. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…lidation common.ts becomes chain, price, migration, feeParams, vesting, swap and quoteSwap. Curve builders reserve the program migration base and use constant product for compounding migrations. Validation mirrors the 0.2.2 transfer-fee rules: constant supply, no locked vesting, Customizable with Compounding, a Token-2022 base fee of at most 10%, and a non-default fee claimer for partner authorities. Quotes of a buildCurve result go through getQuoteFromInputAmount and getQuoteFromOutputAmount. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… export list DynamicBondingCurveClient creates one Anchor program and hands it to the services. createConfig2 sends transferFeeParameters, createConfigAndPool always uses it, and migrateToDammV2, withdrawLeftover and the claim flows follow the transfer-fee rules of the audited program. swapQuote2 quotes an existing pool with its current point. The package root is an explicit export list and the program math is published from the ./math entry. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds transferFee, getQuoteFrom and buildCurveProgramMath tests and updates the validator-backed tests to the 2.0 client. The token badge flow runs against the cp_amm 0.2.5 fixture. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
package.json exposes the root and ./math entries only. tsconfig drops the strictNullChecks override. The changelog, README and docs describe the 2.0 release as of this sync; the docs are regenerated later in the stack. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The memcmp offset was 72, which is PoolConfig.leftover_receiver. The fee claimer sits at 40, after the discriminator and quote_mint. The filter has matched the leftover receiver since 60e8a69; the existing test never noticed because it used one key for both. The new test creates a config with a distinct leftover receiver. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Thanks for porting #120 into this stack, @dannxbt — glad the If it's not too much trouble, would you mind adding a co-author trailer to the migration commit (13e1740)? If the stack gets squash-merged, keeping that line in the final commit message would be appreciated. Totally fine if rewriting the commit is a hassle at this point, just thought I'd ask. Once this lands I'll close #120. |
…down Every segment was compared against the full migration threshold and the terminal segment was credited with the full threshold, so any curve whose threshold spans more than one segment over-allocated and ended at the wrong sqrt price. The breakdown now carries the amount left, stops at exact cumulative completion, and throws when the curve cannot hold the threshold, matching the program's liquidity_distribution. The strict comparison replaces the previous greater-or-equal. This is PR #120 by snuff12 (fixes #119) ported onto helpers/migration.ts, with its regression fixtures. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: snuff12 <snuff12@snu.ac.kr>
…am rejects getFeeSchedulerParams returned a constant fee before checking the 25 to 9900 bps bounds, so (10, 10) and (9950, 9950) produced a cliff fee outside MIN_FEE_NUMERATOR and MAX_FEE_NUMERATOR, and a totalDuration shorter than numberOfPeriod floored the period frequency to zero. Both are InvalidFeeScheduler on chain. An exponential schedule whose ending fee is undershot by even one bps of decay returned a reduction factor of 0, which the program rejects when numberOfPeriod is set; the builder throws instead. The same decay helper serves the migrated market-cap scheduler. getMigratedPoolFeeParams kept a custom migratedPoolBaseFeeMode for the fixed MigrationFeeOptions, which must send mode 0, and silently switched to Customizable whenever marketCapFeeSchedulerParams was set. The market-cap branch was also gated on an unrelated baseFeeParams argument, so without it the scheduler params were dropped and a market-cap mode went out with zero params. Fixed options now throw on a custom mode or scheduler, Customizable requires a market-cap mode exactly when scheduler params are set, and the unused argument is gone. The buildCurve tests move to a shared fixture in tests/utils/curve.ts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
getLockedVestingParams floored totalVestingDuration / numberOfVestingPeriod to zero when the duration was shorter than the period count, and the program rejects a zero frequency (InvalidVestingParameters). The cliff-only path, which moves one token into a single period, needs at least one token to do so. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
validateConfigParameters threw "Invalid fee claimer" for every Token-2022 partner update authority config unless options.feeClaimer was passed; the program only rejects Pubkey::default(), so the rule now applies when a fee claimer is given. The curve shape, the threshold and the start price are checked before getMigrationThresholdPrice runs, so an empty or unordered curve reports "Invalid curve" instead of failing inside the curve math. This is the program's order in process_create_config. validateMigratedPoolFee no longer calls validateMigratedPoolBaseFeeMode inside a try/catch: that call collapsed every base fee mode error into "Invalid migrated pool fee parameters" and made the detailed messages, and the market-cap pool fee check that follows, unreachable. validateConfigParameters already runs the mode validation once. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… config The supply guard threw when the rounding delta equalled the leftover; the program allows the delta to be at most the leftover, so the guard is now strictly greater. A migration base, locked vesting and leftover that exceed the supply surfaced as a SafeMath subtraction overflow from getFirstCurve; buildCurveWithTwoSegments returned an empty curve when none of its mid prices gave positive liquidity, buildCurveWithMidPrice ignored the isOk flag, and buildCurveWithLiquidityWeights read past the end of a short weights array. Each case throws with a message that names the input. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… program getBaseTokenForSwap applied the u64 check to every segment delta and getMigrationThresholdPrice used the u64-checked quote delta. The program (liquidity_distribution.rs) sums in U256 and casts once, so a curve whose single segment exceeds u64 but whose total does not was rejected here and accepted there. Both now use the 256-bit deltas and check the total. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…he config asks for it Every first-buy call site passed enableFirstSwapWithMinFee as true, so the instructions sysvar was appended to every bundled first swap, and the builders also evaluated the rate limiter at activation point 0 although a rate-limiter config can no longer initialize a pool. The builders now take the config's enableFirstSwapWithMinFee flag and nothing else decides the sysvar. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Program 0.2.2 constrains new_creator to differ from creator (InvalidNewCreator). The SDK now fails before sending the transaction. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
PoolConfig.curve is stored with MAX_CURVE_POINT entries and the unused ones are zero. The program skips them in every swap loop and trims them before get_base_token_for_swap. getBaseTokenForSwap, getMigrationThresholdPrice, getCurveBreakdown and getQuoteReserveFromNextSqrtPrice walked the padding, so the first zero point produced a negative delta and threw once the target price reached the last live point. getPoolBaseTokenCurveProgress hit this at migration, and for every pool whose last curve point is the migration price, since its denominator targets that price. liveCurve in ./math is the shared trim. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
6f6b503 to
8b88ee4
Compare
sure, added u in as co-author |
|
Added The same line is at the end of this PR's description, so a squash merge that uses the PR body keeps it on the squash commit. |
bdfe680 to
f960aff
Compare
|
Folded into #123 as a single PR, per review preference. The commits stay on this branch for reading. |
Stack: #123 → #124 (this PR) → #125 → #126. Base: #123.
Ten places where the SDK produced parameters or results the program rejects or computes differently.
getPoolConfigsByOwnerfiltered onleftover_receiver(offset 72). It now filters onfee_claimer(offset 40).getCurveBreakdownconsumes only the remaining threshold per segment, uses a strict comparison, stops at exact completion and throws when the curve cannot hold the threshold. This is fix: honor cumulative thresholds and exact boundaries in getCurveBreakdown #120 by @snuff12 (fixes getCurveBreakdown exceeds cumulative thresholds and overshoots rounded boundaries #119) ported ontohelpers/migration.tswith its fixtures.getFeeSchedulerParamschecks the 25 to 9900 bps bounds for a constant fee too and rejects atotalDurationshorter thannumberOfPeriod. An exponential schedule whose ending fee is unreachable throws instead of emittingreductionFactor0; the migrated market-cap scheduler uses the same helper.getMigratedPoolFeeParamsrejects a custom base fee mode or market-cap scheduler with a fixedMigrationFeeOption, requires a market-cap mode exactly whenmarketCapFeeSchedulerParamsis set, and no longer switches the option to Customizable on its own. Its unused fourth argument is removed.getLockedVestingParamsrejects a period frequency that floors to zero and a cliff-only amount below one token.feeClaimeris passed, since the program rejectsPubkey::default()only. Curve shape, threshold and start price are checked before any curve math runs.validateMigratedPoolFeeno longer swallows the base-fee-mode errors.midPricewith no positive liquidity, and a shortliquidityWeightsarray each throw a named error.getBaseTokenForSwapandgetMigrationThresholdPricesum in U256 and cast once, likeliquidity_distribution.rs.enableFirstSwapWithMinFee. The rate-limiter check at activation point 0 is gone.transferPoolCreatorrejectsnewCreator == creator(programInvalidNewCreator).PoolConfig.curveis stored withMAX_CURVE_POINTentries and the unused ones are zero; the program skips them, the SDK walked them.getBaseTokenForSwap,getMigrationThresholdPrice,getCurveBreakdownandgetQuoteReserveFromNextSqrtPricethrewMath operation overflowonce the target price reached the last live point, which madeclient.state.getPoolBaseTokenCurveProgressthrow at migration, and at any time for a config whose last curve point is the migration price.liveCurveon./mathis the shared trim.Tests:
getCurveBreakdown,feeParams,validation,vestingandstoredCurveunit tests, builder guard tests, a shared curve fixture intests/utils/curve.ts, and validator tests for the fee-claimer filter, the first-buy sysvar and the creator transfer.