// // Button groups // -------------------------------------------------- // Make the div behave like a button .btn-group, .btn-group-vertical { position: relative; display: inline-block; vertical-align: middle; // match .btn alignment given font-size hack above > .btn { position: relative; float: left; // Bring the "active" button to the front &:hover, &:focus, &:active, &.active { z-index: 2; } &:focus { // Remove focus outline when dropdown JS adds it after closing the menu outline: 0; } } } // Prevent double borders when buttons are next to each other .btn-group { .btn + .btn, .btn + .btn-group, .btn-group + .btn, .btn-group + .btn-group { margin-left: -1px; } } // Optional: Group multiple button groups together for a toolbar .btn-toolbar { margin-left: -5px; // Offset the first child's margin &:extend(.clearfix all); .btn-group, .input-group { float: left; } > .btn, > .btn-group, > .input-group { margin-left: 5px; } } .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { border-radius: 0; } // Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match .btn-group > .btn:first-child { margin-left: 0; &:not(:last-child):not(.dropdown-toggle) { .border-right-radius(0); } } // Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it .btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) { .border-left-radius(0); } // Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) .btn-group > .btn-group { float: left; } .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } .btn-group > .btn-group:first-child { > .btn:last-child, > .dropdown-toggle { .border-right-radius(0); } } .btn-group > .btn-group:last-child > .btn:first-child { .border-left-radius(0); } // On active and open, don't show outline .btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { outline: 0; } // Sizing // // Remix the default button sizing classes into new ones for easier manipulation. .btn-group-xs > .btn { &:extend(.btn-xs); } .btn-group-sm > .btn { &:extend(.btn-sm); } .btn-group-lg > .btn { &:extend(.btn-lg); } // Split button dropdowns // ---------------------- // Give the line between buttons some depth .btn-group > .btn + .dropdown-toggle { padding-left: 8px; padding-right: 8px; } .btn-group > .btn-lg + .dropdown-toggle { padding-left: 12px; padding-right: 12px; } // The clickable button for toggling the menu // Remove the gradient and set the same inset shadow as the :active state .btn-group.open .dropdown-toggle { .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); // Show no shadow for `.btn-link` since it has no other button styles. &.btn-link { .box-shadow(none); } } // Reposition the caret .btn .caret { margin-left: 0; } // Carets in other button sizes .btn-lg .caret { border-width: @caret-width-large @caret-width-large 0; border-bottom-width: 0; } // Upside down carets for .dropup .dropup .btn-lg .caret { border-width: 0 @caret-width-large @caret-width-large; } // Vertical button groups // ---------------------- .btn-group-vertical { > .btn, > .btn-group, > .btn-group > .btn { display: block; float: none; width: 100%; max-width: 100%; } // Clear floats so dropdown menus can be properly placed > .btn-group { &:extend(.clearfix all); > .btn { float: none; } } > .btn + .btn, > .btn + .btn-group, > .btn-group + .btn, > .btn-group + .btn-group { margin-top: -1px; margin-left: 0; } } .btn-group-vertical > .btn { &:not(:first-child):not(:last-child) { border-radius: 0; } &:first-child:not(:last-child) { border-top-right-radius: @border-radius-base; .border-bottom-radius(0); } &:last-child:not(:first-child) { border-bottom-left-radius: @border-radius-base; .border-top-radius(0); } } .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } .btn-group-vertical > .btn-group:first-child:not(:last-child) { > .btn:last-child, > .dropdown-toggle { .border-bottom-radius(0); } } .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { .border-top-radius(0); } // Justified button groups // ---------------------- .btn-group-justified { display: table; width: 100%; table-layout: fixed; border-collapse: separate; > .btn, > .btn-group { float: none; display: table-cell; width: 1%; } > .btn-group .btn { width: 100%; } > .btn-group .dropdown-menu { left: auto; } } // Checkbox and radio options // // In order to support the browser's form validation feedback, powered by the // `required` attribute, we have to "hide" the inputs via `opacity`. We cannot // use `display: none;` or `visibility: hidden;` as that also hides the popover. // This way, we ensure a DOM element is visible to position the popover from. // // See https://github.com/twbs/bootstrap/pull/12794 for more. [data-toggle="buttons"] > .btn > input[type="radio"], [data-toggle="buttons"] > .btn > input[type="checkbox"] { position: absolute; z-index: -1; .opacity(0); } .elementor-animation-grow-rotate { transition-duration: 0.3s; transition-property: transform; } .elementor-animation-grow-rotate:active, .elementor-animation-grow-rotate:focus, .elementor-animation-grow-rotate:hover { transform: scale(1.1) rotate(4deg); } Why AMMs on Polkadot Demand More Than Just “Put in Liquidity and Wait” – Smart Porteria Virtual

Why AMMs on Polkadot Demand More Than Just “Put in Liquidity and Wait”

Whoa!

I used to think AMMs were just simplified markets for swaps.

They looked elegant on paper and pretty straightforward to a newbie trader.

But after spending months providing liquidity on a few Polkadot-based pools and watching fees roll in while also seeing positions shrink because of price divergence, my instinct said the story was more complicated, and that complexity matters for anyone moving real capital.

Initially I thought that impermanent loss was the main villain, though actually what surprised me more was how fee structures, token correlation, and chain-specific mechanics like XCMP liquidity routing can make outcomes very different from expectations even when you do everything «by the book».

Seriously?

Yep, seriously.

Impermanent loss gets shouted about a lot, and for good reason.

On one hand it’s easy to calculate loss relative to HODLing with the constant product formula, but on the other hand short-term fee income, protocol incentives, and concentrated liquidity features introduce moving parts that change the practical tradeoff for an LP, especially in volatile DOT-parachain asset pairs.

I’ll be honest—sometimes the math felt like a riddle, and I had to step through scenarios slowly, recalculating expected returns with different price paths and fee regimes to get a realistic sense of risk, which is work many casual LPs won’t do.

Hmm…

Let me break down the core idea simply.

An automated market maker like a Uniswap-style CPAMM auto-balances tokens so trades can happen without order books.

That simplicity is powerful because it creates continuous liquidity, but it also creates impermanent loss whenever the relative price of the two tokens moves away from the pool’s starting ratio, which is felt as an opportunity cost measured against simply holding the assets.

In practice, though, experienced LPs look beyond the raw IL number and consider fee accrual, distribution of trades, arbitrage dynamics, and the correlation between pair tokens, because two volatile tokens that move together may incur far less practical IL than a volatile token paired with a stable asset.

Here’s the thing.

Correlation matters a ton.

If you’re providing liquidity for two tokens that trend together, the pool may be safer than it appears.

On Polkadot you can find pairs like two parachain project tokens or wrapped assets that are tightly correlated thanks to shared fundamentals or cross-chain mechanisms, and those pairs can yield attractive returns with lower realized impermanent loss over typical trading horizons, though that depends on how often arbitrageurs rebalance the pool.

So you can’t just copy a strategy from Ethereum and expect identical results; the network-level differences and liquidity routing (and even different user behavior in Polkadot DEX UIs) change the odds and your spreadsheet assumptions.

Okay—so?

You want practical guardrails.

Start with small allocations and simulate.

Use historical price paths to model IL and fee capture over the periods you care about, and if your platform supports concentrated liquidity or tick ranges, experiment with narrower ranges to boost fee share while accepting localized exposure, because concentrated strategies amplify both fees and risk in ways that are intuitive but easy to mis-size without backtesting.

And don’t forget about gas and cross-chain transfer costs on Polkadot—while transaction fees are lower than some L1s, moving assets between parachains or bridging introduces slippage and timing risk that can alter your effective returns when you enter or exit positions.

Check this out—

I once provided liquidity to a DOT/USDT-like pair on a new parachain DEX.

At first the APR looked irresistible because of token rewards and active trading.

But after a week of asymmetric price moves and a few large swaps that shifted the pool ratio, the amplified impermanent loss combined with a delayed reward vesting schedule meant my net position lagged a simple buy-and-hold, which taught me to value liquidity mining timing as much as headline APYs.

That experience pushed me to favor protocols that offer on-chain analytics and granular position controls so I can close or adjust exposure quickly if a pair starts diverging beyond my tolerance, because in fast markets delays are costly and dashboards that lag on Polkadot front-ends can be a real pain.

Dashboard showing AMM pool performance and impermanent loss projections

How to think like an LP on Polkadot

Not all hope’s lost.

There are ways to tilt the odds in your favor.

Some protocols add dynamic fees, which increase during high volatility and reward LPs when they endure bigger price swings.

Others let you set ranges or use virtual AMMs that mimic concentrated liquidity without the same on-chain repositioning costs.

For traders on Polkadot this means choosing DEXs that offer composable primitives and low friction for moving positions between strategies, so you can capture fees when markets are calm and narrow your exposure when they aren’t, but you have to be mindful of cross-parachain latency and router behavior that can delay execution.

A word on fees.

Fees are the counterbalance to IL.

If your pool experiences steady swapping volume, fee income can more than offset temporary losses.

However the type of traders matters—a pool dominated by arbitrage or sandwich attacks generates different fee patterns than one with organic retail flow.

So when you evaluate a Polkadot AMM, look at fee sources, the nature of traded flows, and whether the protocol has anti-MEV protections or MEV mitigations, because that will affect both realized returns and tail risks in ways raw APR numbers hide.

Also—

Watch reward tokens carefully.

Many liquidity incentives are paid in native project tokens, and that tilts your exposure.

If those tokens are volatile or illiquid, your apparent APY can evaporate fast when you try to convert them to stable assets.

Therefore it’s often wiser to treat rewards as optional upside and size your primary capital with the expectation of fee income alone, and if you must take rewards, consider automated strategies that sell into fees on a schedule to avoid being stuck with concentrated token exposure.

Risk controls help.

Set stop thresholds and rebalancing rules.

Automate what you can but keep manual overrides for black swan events.

If the DEX integrates with on-chain tools that let you migrate positions or collect fees without full withdrawals, you’ll save on costs and slippage.

My instinct says many retail LPs underestimate operational risk—losing time on migrating positions, paying unnecessary bridge fees, or misreading a reward cliff can turn a profitable strategy into a loss after you account for real-world frictions.

Okay, practical checklist.

First, check token correlation and historical volatility.

Second, model IL against expected fee income for your intended horizon.

Third, understand the DEX’s fee schedule, reward vesting, and any concentrated liquidity features.

Fourth, account for chain-specific factors on Polkadot like cross-chain messaging delays, parachain liquidity depth, and router designs that might route trades in ways that change your expected fee capture or slippage when the market moves.

One more thing.

Liquidity tools are evolving fast.

New primitives let LPs express more nuanced exposure with less constant on-chain maintenance.

I recommend exploring projects with transparent analytics and active developer communities, because good tooling reduces surprise and friction.

If you’re curious about a Polkadot-native DEX that aims to combine deep liquidity, nuanced LP controls, and clear UI metrics (and I might be biased here), check the asterdex official site to see how some of these ideas are being implemented in real products.

FAQ

What exactly is impermanent loss?

Impermanent loss is the relative difference in value between holding tokens in an AMM pool versus holding them in your wallet; it manifests when the price ratio changes, and it’s «impermanent» because if prices revert your loss can shrink, though fees and other factors determine final outcome.

Can fees fully offset impermanent loss?

Sometimes they can, especially in high-volume pools with natural trading flow, but it’s not guaranteed—look at trade composition, reward structure, and your time horizon before assuming fees will save you.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio