Skip to content

Conversation

@ruixhuang
Copy link
Contributor

  • Fetching params from validator using v4-client-js
  • Saving params into internal state
  • Adjusting trading fees based on the params

Also ran codegen to update some of the indexer data models

@ruixhuang ruixhuang marked this pull request as ready for review October 31, 2025 15:38
): Double? {
if (fee == null) return fee

var finalFee = fee
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tqin7 @jaredvu Please verify the fee calculation logic here. Thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

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

do you need to check if finalFee *= marketFeeDiscount.chargePercent is greater than 0 before applying the userStakingTierDiscountPercent?

@tqin7 would it ever be negative?

import kotlinx.serialization.Serializable

@Serializable
data class OnChainFeeDiscountsResponse(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Those are hand-coded based on the the v4-client data model. @Sam-dYdX @qardpeet

@@ -0,0 +1,26 @@
/**
* Indexer API
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Data models from indexter codegen... You can ignore those @Sam-dYdX @qardpeet

}

private fun retrieveUserStakingTier() {
val params = iMapOf("address" to accountAddress)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is where Abacus calls the validator to fetch data. Native code implements the actual fetching logic and calls the v4-client-js function using javascript bridge. @Sam-dYdX @qardpeet

existing: InternalUserState?,
payload: OnChainUserStakingTierResponse?,
): InternalUserState {
val internalState = existing ?: InternalUserState()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Parsing the response object and store the relevant content into the internal state (to be used by subsequent calculation). @Sam-dYdX @qardpeet


internal fun TradingStateMachine.onChainUserStakingTier(payload: String): StateChanges {
val json = parser.decodeJsonObject(payload)
val payload = parser.asTypedObject<OnChainUserStakingTierResponse>(json)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deserialize the validator payload to a static model here.. @Sam-dYdX @qardpeet

try {
val newValue = PerpetualMarket(
id = name,
clobPairId = payload.clobPairId,
Copy link
Collaborator

Choose a reason for hiding this comment

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

nice

val feeDiscountState = InternalMarketFeeDiscountState(
startTime = feeDiscount.startTime,
endTime = feeDiscount.endTime,
chargePercent = feeDiscount.chargePpm?.div(QUANTUM_MULTIPLIER),
Copy link
Collaborator

Choose a reason for hiding this comment

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

chargePpm / 1e6 🔥

@ruixhuang ruixhuang merged commit 76e61cd into main Nov 3, 2025
3 checks passed
@ruixhuang ruixhuang deleted the feature/fees branch November 3, 2025 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants