Skip to content

fix: adjust stablecoin outstanding supply for reserve holdings and lost tokens#88

Merged
bowd merged 12 commits intomainfrom
feat/fix-accounting
Jan 29, 2026
Merged

fix: adjust stablecoin outstanding supply for reserve holdings and lost tokens#88
bowd merged 12 commits intomainfrom
feat/fix-accounting

Conversation

@bowd
Copy link
Contributor

@bowd bowd commented Jan 28, 2026

Summary

This PR moves reserve accounting logic from the SDK into the API. The SDK will now return raw on-chain totalSupply values (see mento-sdk#116), and the API handles all adjustments for accurate outstanding supply calculation.

Stablecoin Accounting Fixes

  • Subtract stablecoins held by reserve addresses from total outstanding supply
  • Subtract stablecoins deposited in AAVE by the reserve from outstanding supply
  • Subtract "lost tokens" (stablecoins held by their own contract addresses) from outstanding supply
  • Remove USDm/EURm from reserve AAVE holdings (they're liabilities, not assets)
  • Adjustments are applied per-token so individual stablecoin supplies are also adjusted

Reserve Address Updates

  • Add Falcon Finance Custodied Funds address (0x619600F4ec13C38868841cB83100F611eCF94eE8)
  • Remove Celo Community Shared Reserve

Performance Improvements

  • Parallelize balance fetches in stablecoin adjustments service
  • Increase RPC concurrency from 1 to 10 globally, 1 to 5 per-chain
  • Reduce minimum delay between RPC requests from 500ms to 50ms
  • Result: /api/v1/reserve/stats response time reduced from ~62s to a few seconds

SDK Migration

  • Migrate AAVESupplyCalculator from SDK to API (src/common/services/calculators)
  • Migrate UniV3SupplyCalculator from SDK to API
  • Migrate ERC20_ABI and UniV3 ABIs to local constants
  • Add AAVE token mappings config (src/common/config/aave.config.ts)
  • Remove ViemAdapter dependency - calculators now use ChainClientService directly
  • Only Mento class is now imported from @mento-protocol/mento-sdk

Test plan

  • Verify /api/v1/stablecoins returns adjusted supplies
  • Verify /api/v1/reserve/stats collateralization ratio uses adjusted outstanding
  • Check logs show adjustment breakdown (Reserve, AAVE, Lost totals)
  • Verify response times are acceptable (<10s for stats endpoint)
  • Monitor for RPC rate limit errors with increased concurrency

🤖 Generated with Claude Code

…st tokens

Subtract from total outstanding stablecoin supply:
- Stablecoins held directly by reserve addresses
- Stablecoins deposited in AAVE by the reserve
- Lost tokens (stablecoins held by their own contract addresses)

Also removes USDm/EURm from reserve AAVE holdings since they are
liabilities, not assets.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot temporarily deployed to preview-88 January 28, 2026 11:01 Destroyed
@github-actions
Copy link

github-actions bot commented Jan 28, 2026

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://analytics-api-preview-feat-fix-accounting-a4neydykmq-uc.a.run.app/docs

📝 Details:

  • Service: analytics-api-preview-feat-fix-accounting
  • Commit: 9fb6436
  • Branch: feat/fix-accounting
  • Updated: 1/29/2026, 10:55:28 AM UTC

This preview will be automatically updated with each new commit to this PR and will be deleted when the PR is merged or closed.

Remove configurable dead addresses - only check tokens held by their
own contract address (self-held tokens that are unrecoverable).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot temporarily deployed to preview-88 January 28, 2026 11:06 Destroyed
Tokens passed to adjustments service already come from Mento SDK's
getStableTokens(), so no need to filter again.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot temporarily deployed to preview-88 January 28, 2026 11:12 Destroyed
…died Funds

Remove Celo Community Shared Reserve (0x9d65E69aC940dCB469fd7C46368C1e094250a400)
and add Falcon Finance Custodied Funds (0x619600F4ec13C38868841cB83100F611eCF94eE8)
tracking CELO tokens on Celo network.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot temporarily deployed to preview-88 January 28, 2026 11:46 Destroyed
Instead of using the totalSupply value returned by the Mento SDK,
fetch it directly from each token contract on Celo.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot temporarily deployed to preview-88 January 28, 2026 12:06 Destroyed
Use Promise.all to fetch all token/holder balance combinations
concurrently instead of sequentially. The rate limiter will still
queue requests appropriately, but this queues them all upfront
rather than waiting for each to complete before starting the next.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot temporarily deployed to preview-88 January 28, 2026 13:19 Destroyed
bowd and others added 2 commits January 28, 2026 14:22
Add [TIMING] logs to:
- Reserve controller getReserveStats
- Reserve service fetchReserveHoldingsInternal
- Stablecoins service getStablecoins
- Stablecoin adjustments service (all methods)

Also parallelize reserve holdings and stablecoins fetch in getReserveStats.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot temporarily deployed to preview-88 January 28, 2026 13:29 Destroyed
Increase global RPC concurrency from 1 to 10, per-chain from 1 to 5,
and reduce minimum delay between requests from 500ms to 50ms.
This dramatically reduces /api/v1/reserve/stats response time from ~62s to a few seconds.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot temporarily deployed to preview-88 January 28, 2026 13:44 Destroyed
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@bowd bowd requested review from bayological and chapati23 January 28, 2026 13:53
@github-actions github-actions bot temporarily deployed to preview-88 January 28, 2026 13:55 Destroyed
import { ExchangeRatesService } from '@/common/services/exchange-rates.service';
import { Chain } from '@types';
import { withRetry, RETRY_CONFIGS } from '@/utils';
import { ERC20_ABI, ViemAdapter, AAVESupplyCalculator } from '@mento-protocol/mento-sdk';
Copy link
Member

Choose a reason for hiding this comment

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

nit: We should have moved this AAVESupplyCalculator along with any of the remaining supply adjustment logic out of the sdk and into the API, since they're no longer being used there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I had the same thought but punted it initially. But I did it in the end.

label: 'Mento Pools Liquidity Reserve',
},
{
address: '0x87647780180b8f55980c7d3ffefe08a9b29e9ae1',
Copy link
Member

Choose a reason for hiding this comment

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

nit: This doesn't break anything, but the same address is lower case here vs checksummed on line 43. Also, acknowledge that I've done the same in the addresses config file..

@github-actions github-actions bot temporarily deployed to preview-88 January 29, 2026 10:41 Destroyed
@github-actions github-actions bot temporarily deployed to preview-88 January 29, 2026 10:55 Destroyed
@bowd bowd merged commit 13b3505 into main Jan 29, 2026
1 check passed
@bowd bowd deleted the feat/fix-accounting branch January 29, 2026 10:55
private blockWatchers = new Map<Chain, () => void>();
private rpcLimiters = new Map<Chain, ReturnType<typeof pLimit>>();
private globalRpcLimiter = pLimit(1);
private globalRpcLimiter = pLimit(10);
Copy link
Contributor

Choose a reason for hiding this comment

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

i vaguely remember that @Andrew718PLTS played a lot with these values to reduce RPC errors we saw in sentry quite frequently

should keep an eye on those errors popping back up, let's see how it works in practice

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