Skip to content

AutobalanceLp pending-rewards function implementation#60

Merged
jangid merged 3 commits intomainfrom
feature/autobalanceLp
Apr 22, 2026
Merged

AutobalanceLp pending-rewards function implementation#60
jangid merged 3 commits intomainfrom
feature/autobalanceLp

Conversation

@11felix
Copy link
Copy Markdown
Contributor

@11felix 11felix commented Apr 21, 2026

  1. Adds autobalanceLpPendingRewardAmount(userAddress, poolId) to the SDK, which returns a user's pending non-ALPHA rewards for an AutobalanceLp pool as a map of reward coin type to decimal string (throws if the pool is not AutobalanceLp). 2. Also migrates a couple of remaining JSON-RPC reads (wallet balances, Bucket TVL) to GraphQL and updates the README.

@11felix 11felix requested a review from jangid as a code owner April 21, 2026 20:29
@11felix 11felix requested a review from Zorag44 April 21, 2026 20:29
Copy link
Copy Markdown
Contributor

@jangid jangid left a comment

Choose a reason for hiding this comment

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

Review Summary

Two changes bundled: (1) new autobalanceLpPendingRewardAmount() function, (2) JSON-RPC → GraphQL migration for coins/balances/simulation/Bucket TVL.

The GraphQL migration portions look solid. The pending-rewards feature works but has a pagination bug in getAllBalances and silent error swallowing that should be addressed before merge.

Comment thread src/models/blockchain.ts
return undefined;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: getAllBalances is not actually paginated. The query accepts a $cursor variable and the response includes pageInfo, but this method never loops — it fetches one page and returns. If a user holds more coin types than fit in a single page, balances will be silently truncated.

The getCoins migration above correctly paginates with a do/while loop — this method needs the same treatment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed

}
}

private collectReward(tx: Transaction) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Silent error swallowing in a financial context. The catch block logs the error and returns {}. Callers cannot distinguish "no pending rewards" from "simulation failed."

At minimum, propagate the error (or return a discriminated result type) so callers know something went wrong. Returning empty data on failure is dangerous when users are making financial decisions based on this output.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Comment thread src/strategies/autobalanceLp.ts Outdated
});
tx.moveCall({
target: `${this.poolLabel.packageId}::alphafi_bluefin_type_1_pool::get_cur_acc_per_xtoken`,
typeArguments: [this.poolLabel.assetA.type, this.poolLabel.assetB.type],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Heavy code duplication. The three branches (assetA.name === 'SUI', assetB.name === 'SUI', else) are nearly identical — only the Move module name differs (sui_first_pool / sui_second_pool / type_1_pool) and version suffix (v4 vs v3). This pattern already exists in collectReward below, but duplicating it again compounds the maintenance burden.

Consider extracting a helper that takes the module name and version string.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Comment thread src/models/blockchain.ts

const query = graphql(`
query simulate($tx: JSON!) {
simulateTransaction(transaction: $tx, checksEnabled: true, doGasSelection: false) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Untyped simulation response. simulateTransaction returns any, and downstream code navigates deeply into res?.outputs?.[res.outputs.length - 1]?.returnValues?.[0]?.value?.json?.contents. If the GraphQL schema changes, this will silently break at runtime.

A typed response interface would catch regressions at compile time.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Comment thread src/strategies/autobalanceLp.ts Outdated
.mul(userXtokenBalance)
.div(1e36)
.plus(pending)
.div(Math.pow(10, decimals))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: 1e36 is a magic number — a named constant would clarify its meaning (presumably accumulated reward precision scaling). Also, type as a variable name shadows the TypeScript keyword; rewardType would be clearer.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Copy link
Copy Markdown
Contributor

@jangid jangid left a comment

Choose a reason for hiding this comment

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

Re-review

All five issues from the previous review have been addressed:

  1. getAllBalances pagination — fixed, proper cursor loop now in place
  2. Silent error swallowing — fixed, errors propagate to callers
  3. Code duplication — partially fixed via getPoolModule() / getUpdatePoolFn() helpers
  4. Untyped simulation response — fixed, typed interfaces in types.ts
  5. Magic number + variable naming — fixed, ACC_REWARD_PER_XTOKEN_PRECISION constant + rewardType

Minor follow-up: collectReward() and getUserRewards() still repeat the three-branch pattern that getPoolModule() was introduced to eliminate. Tracked in a separate issue — not blocking this PR.

@jangid jangid merged commit 16ce469 into main Apr 22, 2026
3 checks passed
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