Skip to content

Broker: Introduce min price + adjust renewals to lower market.#8630

Merged
eskimor merged 26 commits intomasterfrom
rk-coretime-min-price
May 30, 2025
Merged

Broker: Introduce min price + adjust renewals to lower market.#8630
eskimor merged 26 commits intomasterfrom
rk-coretime-min-price

Conversation

@eskimor
Copy link
Copy Markdown
Member

@eskimor eskimor commented May 23, 2025

This PR provides:

  1. The means for the runtime to configure a minimum price for sales.
  2. Prevents renewals to get detached too much from current market, by bumping them at least to the end_price of the current sale.

TODO:

  • Implement
  • Add tests
  • Fix runtimes/Make Rococo + Westend use the new price controller.
  • prdoc
  • Leave configurability to the runtime

@eskimor eskimor requested a review from a team as a code owner May 23, 2025 13:55
/// price and makes sure that the returned `end_price` is never lower than that.
///
/// Target price will also get adusted if necessary (it will never be less than the end_price).
pub struct MinimumPrice<Balance, MinPrice>(core::marker::PhantomData<(Balance, MinPrice)>);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We don't really need this pr? We can just move this to the coretime-chain in the fellowship repo and add the minimum price check?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Except that we do need some pallet to have the minimum price configurable. Also this PR adjusts renewals if they drop too low compared to current market price.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No we don't need to. The minimum price could be placed into the parameter pallet for example (if it really needs to be configurable)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Interesting, wasn't aware of this pallet. Are we talking about this one. If so, it says it should not be used in production?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'll suggest we go with static values for now. That parameters is not yet on Polkadot and apparently should also not be there (not audited yet), so we could only use it on Kusama anyways.

@eskimor
Copy link
Copy Markdown
Member Author

eskimor commented May 23, 2025

/cmd prdoc

@paritytech paritytech deleted a comment from github-actions bot May 23, 2025
@paritytech paritytech deleted a comment from github-actions bot May 23, 2025
@eskimor eskimor added T8-polkadot This PR/Issue is related to/affects the Polkadot network. A4-backport-stable2503 Pull request must be backported to the stable2503 release branch labels May 23, 2025
@paritytech-workflow-stopper
Copy link
Copy Markdown

All GitHub workflows were cancelled due to failure one of the required jobs.
Failed workflow url: https://github.com/paritytech/polkadot-sdk/actions/runs/15272456686
Failed job name: fmt

@eskimor eskimor removed the A4-backport-stable2503 Pull request must be backported to the stable2503 release branch label May 27, 2025
Copy link
Copy Markdown
Contributor

@Overkillus Overkillus left a comment

Choose a reason for hiding this comment

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

I have no concerns about the code itself. All looks fine and tested.

I have some questions or remarks about the overall behaviour though. As of the sale happening today the current auction max price was 98 DOT. Next cycle as far as I understand the new max price will be around 1000 DOT since all cores are sold out. If we would merge and activate this PR then if there are some cores on sale next month, and if those cores are sold for 1k DOT then all renewals will jump to 1k DOT. Are we ready for that? Do we plan to communicate it? Because I am afraid this will start a nuclear shitstorm in the community. We were promising teams stability and then boom, 1k DOT for a renewal.

I was on stage at Sub0 telling teams that they can expect at most 66% year on year renewal price increase and this is on record. And now we are doing a reverse rugpull here. This HAS to be insanely clearly communicated and it has to be the decision of the token holders and not a random obscure and obfuscated vote.

I know we need to fix the current situation so I don't intend to block it, but just wondering how we can do it with the least amount of damages.


If we'd set the minimum to sth like 100 dot then we could keep the old price renewal price scaling model. Wouldn't it be enough of a deterrent to the baron? If he wants to hoard 20 cores -> 20*100DOT = 2k DOT per month just to maintain the attack.

Issue is now the renewals are borderline free but bumping them to clearing price seems very aggressive considering we can go 10x each cycle. This PR changes renewals from max 1.66x per year to max 10^12 = 100_000_000_000x per year 😅

@eskimor
Copy link
Copy Markdown
Member Author

eskimor commented May 28, 2025

Where are those 1k Dot coming from? If we add more cores, renewals should be 10 Dot. But even if all cores sold out at 1k, then renewals would still be 100 Dot and not 1k.

Renewals would still be relatively stable - you only get adjusted if the market goes >10x and only if you managed to get a renewal at a bargain. If you bought at current market price, then market needs to go 100x for your price to be affected.

So yes, we are breaking the price stability a bit, but only marginally (biggest change will be the introduction of the minimum price) and we seemed to have broad agreement that this is needed: We need to adjust to current market at least a bit.

@Overkillus
Copy link
Copy Markdown
Contributor

Overkillus commented May 28, 2025

Didn't know we plan to inject some new cores. This makes me a bit calmer, but the question is how many cores?

We are at cycle N. Max price in cycle N was 100 DOT and that was also the end price. A new auction cycle N+1 is starting in a few days. The maximum in cycle N+1 will be 10x100 = 1k DOT. Renewals in N+1 would be (if this change enacts) 100 dot. If someone buys the remaining cores in N+1 for 1k DOT then N+2 renewals will be 1k DOT.

Imagine we inject a single core at N+1. Then in N+1 the attacker needs to buy a single core for 1k DOT to raise the renewals to 1k in N+2.

If we injected more cores then this isn't such a big deal as buying all gets expensive.

This ties the price of renewals very heavily to the price of the last core and opens up for some abuse. It is one thing to make new potential customers unhappy when no cores are available (delaying their launch) but skyrocketing renewals might piss off current loyal clientele.

@eskimor
Copy link
Copy Markdown
Member Author

eskimor commented May 28, 2025

End price is not the clearing price, it is the lowest price that can be reached in the Dutch auction. If all cores are sold at 1k, then the end price will be raised from 10 Dot to 100, which is what renewals would be adjusted to.

They still have plenty of price stability. In the sense that the market went 100x, while they only suffered a 10x.

eskimor and others added 2 commits May 28, 2025 22:10
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
@Overkillus
Copy link
Copy Markdown
Contributor

Overkillus commented May 29, 2025

End price is not the clearing price, it is the lowest price that can be reached in the Dutch auction.

That makes sense. I initially misunderstood the end_price param. This makes it a lot more expensive to manipulate.

Even in the worst possible scenario the attacker has to spend roughly 100x of what the next renewals will be so considering there are around 100 cores being renewed does not lead to an amplification attack.
In fact it is 10x. Attacker can just not buy cores in last cycle but renewals will stil adjust to end_price. So there is a bit of an amplification attack.

Attack gets much harder when there are more that 1 core on sale. Overall I'm slightly worried about an attack here. It is still expensive but possible.


Let's assume we bump minimum to 10 DOT.

Cycle N: (current)
start_price = 100 DOT
end_price = 1 DOT

Cycle N+1:
renewals = max(10, 1) = 10 DOT
start_price = 1k DOT
end_price = 10 DOT

Renewals will still be a neglibile cost for the Baron. He can continue hoarding his cores.
The start_price in open market is already quite noticeable should be a major deterrant against attacks sniping all at the start.

Cycle N+2:
renewals = max(10, 10) = 10 DOT
start_price = 10k DOT
end_price = 100 DOT

Hoarding is still very cheap even with 20x cores. Buying on open market got quite expensive. Unlikely someone buys all cores for 10k now. If someone did...

Cycle N+3:
renewals = max(10, 100) = 100 DOT
start_price = 100k DOT
end_price = 1000 DOT

Renewals bump quite a lot and hoarding gets expensive (20*100 = 2k DOT per month). Onboarding gets expensive as well with 1k DOT per core minimum but not unfeasible. Sniping gets borderline impossible with 100k DOT per core.

Getting to this state will take us 3 months.

Cycle N+4:
renewals = max(10, 1000) = 1000 DOT

Just to be clear we can reach this renewal price EVEN if the cores dont sell out in N+3.


If we would inject 2 cores per month. Total cost of starting with 20 + buying all each month is:

N: 20x10 + 2x100 = 400
N+1: 22x10 + 2x1k = 2_220
N+2: 24x10 + 2x10k = 20_240
N+3: 26x100 + 2x100k = 202_600

N+3 becomes completely unreasonable to snipe but renewals are still 100 dot which is a sensible price.

N+4 renewals will be 1k DOT even if the cores dont sell out for 100k. This might be a bit of an issue. Assuming we inject 2 cores this will be roughly 23k DOT to bring all renewals to 1k and if there is only a single core it will be 10k ish.

I think a minimum of 10 DOT is a bit too little and renewals don't matter untill we are 3 months in. 50 DOT should be a stronger deterrant while still being cheap for actual teams.

@eskimor eskimor added this pull request to the merge queue May 30, 2025
Merged via the queue into master with commit 1a8313f May 30, 2025
181 checks passed
@eskimor eskimor deleted the rk-coretime-min-price branch May 30, 2025 16:56
@paritytech-release-backport-bot
Copy link
Copy Markdown

Created backport PR for stable2412:

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin backport-8630-to-stable2412
git worktree add --checkout .worktree/backport-8630-to-stable2412 backport-8630-to-stable2412
cd .worktree/backport-8630-to-stable2412
git reset --hard HEAD^
git cherry-pick -x 1a8313fb2f88053e931370811973e8ce0394686a
git push --force-with-lease

paritytech-release-backport-bot bot pushed a commit that referenced this pull request May 30, 2025
This PR provides:

1. The means for the runtime to configure a minimum price for sales.
2. Prevents renewals to get detached too much from current market, by
bumping them at least to the `end_price` of the current sale.

TODO:

- [x] Implement
- [x] Add tests
- [x] Fix runtimes/Make Rococo + Westend use the new price controller.
- [x] prdoc
- [x] Leave configurability to the runtime

---------

Co-authored-by: Robert <robert@gonimo.com>
Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
(cherry picked from commit 1a8313f)
@paritytech-release-backport-bot
Copy link
Copy Markdown

Successfully created backport PR for stable2503:

eskimor added a commit that referenced this pull request May 30, 2025
This PR provides:

1. The means for the runtime to configure a minimum price for sales.
2. Prevents renewals to get detached too much from current market, by
bumping them at least to the `end_price` of the current sale.

TODO:

- [x] Implement
- [x] Add tests
- [x] Fix runtimes/Make Rococo + Westend use the new price controller.
- [x] prdoc
- [x] Leave configurability to the runtime

---------

Co-authored-by: Robert <robert@gonimo.com>
Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
EgorPopelyaev added a commit that referenced this pull request Jun 4, 2025
Backport #8630 into `stable2503` from eskimor.

See the
[documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md)
on how to use this bot.

<!--
  # To be used by other automation, do not modify:
  original-pr-number: #${pull_number}
-->

Co-authored-by: eskimor <eskimor@users.noreply.github.com>
Co-authored-by: Robert <robert@gonimo.com>
Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
Co-authored-by: Egor_P <egor@parity.io>
ordian added a commit that referenced this pull request Jun 4, 2025
* master:
  omni-node: fix `benchmark pallet` to work with `--runtime` (#8594)
  Handle and suppress "New unknown `FromSwarm` libp2p event" warning (#8731)
  Implement detailed logging for XCM failures (#8724)
  [pallet-revive] contract's nonce starts at 1 (#8734)
  sync/fix: Clear gap sync on known imported blocks (#8445)
  [PoP] Add personhood tracking pallets (#8164)
  client/net: Use litep2p as the default network backend (#8461)
  Unflake `returns_status_for_pruned_blocks` (#8709)
  [AHM] Report the weights of epmb pallet to expose kusama and polkadot weights (#8704)
  Remove all XCM dependencies from `pallet-revive` (#8584)
  Docker master image tag fix (#8711)
  Record ed as part of the storage deposit (#8718)
  [pallet-revive] update dry-run logic (#8662)
  feat: add collator peer ID to ParachainInherentData (#8708)
  Nest errors in pallet-xcm (#7730)
  pallet-assets ERC20 precompile (#8554)
  Broker: Introduce min price + adjust renewals to lower market. (#8630)
  [AHM] Staking async fixes for XCM and election planning (#8422)
  Staking (EPMB): Add defensive error handling to voter snapshot creation and solution verification (#8687)
EgorPopelyaev pushed a commit that referenced this pull request Jun 10, 2025
Backport #8630 into `stable2412` from eskimor.

See the
[documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md)
on how to use this bot.

<!--
  # To be used by other automation, do not modify:
  original-pr-number: #${pull_number}
-->

---------

Co-authored-by: eskimor <eskimor@users.noreply.github.com>
Co-authored-by: Robert <robert@gonimo.com>
Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
pgherveou pushed a commit that referenced this pull request Jun 11, 2025
This PR provides:

1. The means for the runtime to configure a minimum price for sales.
2. Prevents renewals to get detached too much from current market, by
bumping them at least to the `end_price` of the current sale.

TODO:

- [x] Implement
- [x] Add tests
- [x] Fix runtimes/Make Rococo + Westend use the new price controller.
- [x] prdoc
- [x] Leave configurability to the runtime

---------

Co-authored-by: Robert <robert@gonimo.com>
Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
alvicsam pushed a commit that referenced this pull request Oct 17, 2025
This PR provides:

1. The means for the runtime to configure a minimum price for sales.
2. Prevents renewals to get detached too much from current market, by
bumping them at least to the `end_price` of the current sale.

TODO:

- [x] Implement
- [x] Add tests
- [x] Fix runtimes/Make Rococo + Westend use the new price controller.
- [x] prdoc
- [x] Leave configurability to the runtime

---------

Co-authored-by: Robert <robert@gonimo.com>
Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A4-backport-stable2503 Pull request must be backported to the stable2503 release branch T8-polkadot This PR/Issue is related to/affects the Polkadot network.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants