[V136] POL Reserve: route 5% of swap fees to protocol owned liquidity

Summary

Port THORNode's POL Reserve ("System Income POL", thornode 8827b9bd07) to MAYAChain. From 1.136.0, 5% of swap liquidity fees goes to a new pol_reserve module, which adds it to pools as protocol owned liquidity.

Fee split from 1.136.0

Destination Before After
Bond / LPs 80% 75%
MayaFund 10% 10%
CACAOPool (if enabled) 5% 5%
MayaAutoBuyer 1% 1%
Reserve 4% 4%
pol_reserve — 5%
  • Mimir: POLReserveSystemIncomeBps (default 500) sets the share. It comes out of the bond/LP share and is capped at 8000. Setting it to 0 returns that 5% to bond/LPs.
  • Why the base differs from THORNode: MAYAChain has no block emission, so the base is swap liquidity fees only.

Deployment (POLReserveCycle, every block)

  • Pool choice: adds up to POLReserveMaxDeployment CACAO (default 100 CACAO) to one pool per block. It picks the eligible pool with the highest liquidity fees over the last pool cycle relative to its CACAO depth.
  • Eligibility: gas-asset pools are eligible by default. POLReserveWhitelist-<ASSET>=1 adds a pool (for example a stablecoin pool) and POLReserveBlacklist-<ASSET>=1 removes one; the blacklist wins. THORNode also includes TOR-anchor pools by default; MAYAChain has no TOR anchors.
  • Skipped pools: the cycle skips pools that are not Available, empty, or on a chain with halted trading or paused LP. It also does nothing during a global trading halt or ragnarok.
  • Add-only, like THORNode: there is no withdrawal path.
  • Fee ranking: the network manager keeps a per-pool-cycle fee snapshot (pol_reserve_cycle_fee/, pol_reserve_prev_cycle_fee/). MAYAChain never resets the rolling liquidity fee of gas pools, so that fee would always rank gas pools first. This also leaves PoolMgr untouched.

Other changes

  • Outbounds: native outbounds to pol_reserve go module-to-module. The module is a blocked bank address, so a module-to-account send would fail, for example when a ragnarok withdraws its LP.
  • Module account rules: IsModuleAccAddress (V136) includes pol_reserve, so MsgSend and swap destinations cannot target it, the same as the other modules.
  • Events:
    • New event pol_reserve_deploy with pool and cacao_amount.
    • New field EventRewards.pol_reserve_reward. It is set but not emitted as an attribute, like cacao_pool_reward, maya_fund_reward and maya_auto_buyer_reward, so Midgard's rewards parsing is unchanged.
  • Genesis: pol_reserve_deposits (field 41).
  • Docs: the new mimirs are documented in docs/mimir.md.

Versioning

  • version is now 1.136.0.
  • NetworkMgrV135 and TxOutStorageV133 are verbatim frozen copies (first commit). scripts/lint-versions.bash shows no body changes in versioned functions.
  • Changed for 1.136.0:
    • NetworkMgrVCUR and TxOutStorageVCUR, now gated at 1.136.0
    • new isModuleAccAddressV136
  • New constants: POLReserveSystemIncomeBps and POLReserveMaxDeployment.
  • No store migration: the new state starts empty.

Differences from THORNode

  • Mimir classification: POLReserveSystemIncomeBps and the whitelist/blacklist keys are not operational mimirs, so changing them needs the normal economic vote. THORNode lets 3 nodes set them.
  • Not ported:
    • Stable Reserve: needs an oracle price feed and secured assets.
    • Pool query fields: pol_reserve_*_deposited and the rolling fee are not added to the pool query. Deposits can be read through /mayachain/pool/<asset>/liquidity_provider/<pol_reserve address>.

Tests

  • Unit:
    • manager_network_pol_reserve_test.go: best-pool selection, cap, eligibility precedence, skips (halts, LP pause, staged pools, deployment disabled), ranking on the completed pool cycle, and the split at default, 0 and clamped bps
    • keeper_pol_reserve_test.go
    • native outbound to pol_reserve
    • isModuleAccAddressV136
    • updated TestUpdateNetwork (bond 80% → 75%)
  • Lint: scripts/lint-versions.bash reports no body changes in versioned functions, so this needs no #check-lint-warning.
  • Regression: 142/142 with EXPORT=1.
    • New suites/pol/pol-reserve.yaml covers:
      • the Reserve → pol_reserve transfer (exactly 5% of liquidity fees)
      • the same-block deploy to BTC
      • the blacklist moving deployment to ETH
      • the deployment cap
      • deployment disabled while income still accrues
      • income disabled
    • ragnarok.yaml: the ETH pool now also holds a pol_reserve LP, so with RagnarokProcessNumOfLPPerIteration=2 one user LP is left for the second iteration. New checks confirm the pol_reserve LP is withdrawn and its CACAO returns Asgard → pol_reserve, which exercises the outbound fix.
    • Every other suite with swaps changes value because bond/LP rewards and pool depths shift. Values were refreshed with AUTO_UPDATE. Hard-coded observed-out amounts, quote memo limits and derived amounts were fixed by hand.

Addresses

pol_reserve module: maya1fns25sytpf2gsdlg76g45620u5axm4mkrnlv48 (mainnet), tmaya1fns25sytpf2gsdlg76g45620u5axm4mk8ywuvz (regtest).

Merge request reports

Loading
Loading