It buys a stock, marks it up 50%, and every sale burns the coin.
Markup Machine is one public contract on Robinhood Chain. It collects the Pons creator fees of $MARKUP, buys an official Robinhood stock token, lists it for sale at 50% above what it paid, and when the sale fills, the proceeds buy $MARKUP and burn it. Everything below can be checked on-chain.
01What it is
$MARKUP launches on Pons V2 with the MarkupMachine contract set as the coin's creatorFeeRecipient. Every trade of $MARKUP on Pons pays a creator fee in ETH, and that fee belongs to the machine, not to a person.
The machine does five things, always in the same order, and each step is a public transaction:
- One contract, not a fund. There is no owner withdraw. Nothing can move the stocks, USDG or ETH to an arbitrary address.
- The sell order is public. Each listing is a Uniswap V3 position anyone can look up. You can see exactly where the machine will sell.
- Burns are the only exit. Sale proceeds and the burn bucket buy $MARKUP and send it to
0x…dEaD. - No yield, no promise. The machine does not pay anyone. Whether a listing ever sells depends on the stock market.
02How it works
The machine has five parts. The landing page takes it apart in this order.
Fee hopper
harvest() is permissionless. It sweeps the Pons creator fees (from the bonding curve, or the Pons V4 hook after graduation), claims them from the Pons fee escrow, and splits the ETH: 85% to the pot, 10% to the burn bucket, 5% to dev.
Pot tank
ETH waits in the pot until it reaches the minimum buy of 0.05 ETH. The pot only ever pays for stock purchases. Swap fees a listing collects while the price is crossing its range also flow back into it.
Buy arm
buy() swaps the whole pot ETH → USDG → the next stock on Uniswap V3, NVDA first, then TSLA, round-robin. Before it trades, it checks spot against the pool's 30-minute TWAP on both legs and refuses if they differ by more than 1.5%.
Listing rack
In the same transaction, the machine lists every share it just bought for sale at buy price × 1.5 in dollars, as a one-tick sell order in the stock/USDG pool (see What a listing is). It collects the pool's swap fee only while the price is inside its one-tick range (while it is filling), not while it waits below the ask; collectFees() sends that back to the pot.
Burn furnace
When the stock trades through the ask, the order turns into USDG. Anyone can call settle(): the machine takes the USDG out, swaps it to ETH, buys $MARKUP and burns it. burnNow() does the same with the 10% burn bucket.
03Parameters
Start values at deploy. Read them live with params() on the machine.
| Parameter | Value | Can change? |
|---|---|---|
Markup markupBps | +50% in dollars (15000 bps): ask = buy price × 1.5 | Raise only |
Fee split potBps · burnBps · devBps | 85% · 10% · 5% | Burn raise only, dev lower only |
Minimum buy minBuyEth | 0.05 ETH | Bounded config |
TWAP window twapWindow | 30 min (1800 s), never below 10 min | Bounded config |
Max deviation maxDeviationBps | ±1.5% spot vs TWAP (150 bps), never above 3% | Bounded config |
Public buy delay publicBuyDelay | 6 h after the last buy, anyone may call buy() | Bounded config |
| Stocks | NVDA (NVDA/USDG 0.05%), then TSLA (TSLA/USDG 0.3%), round-robin | Add after a 48 h timelock |
| Route | ETH → USDG (USDG/WETH 0.01%) → stock, Uniswap V3 | Fixed |
The markup is in dollars: NVDA bought at $200.00 lists at $300.00. Tick rounding always rounds the ask up, never below +50%.
04What a listing is
A Uniswap V3 position holds liquidity between two prices. If that range is one tick wide and holds only the stock, it behaves like a limit sell order: as soon as the market trades up through the range, the pool swaps the stock into USDG at that price.
- 100% stock now, 100% USDG after the ask. The range is placed just above buy × 1.5 so it holds only stock when it is created and only USDG once the price has passed it.
- Orientation is handled. In the NVDA pool NVDA is token1 (price going up moves the tick down); in the TSLA pool TSLA is token0. The contract rounds toward the side that keeps the ask at or above +50%.
- Filled = fully crossed.
isFilled(id)is true only when the current tick is past the whole range.settle()refuses before that. - It can un-fill. If the price crosses the ask and then falls back before anyone calls
settle(), the pool swaps the USDG back into stock and the order is waiting again. - It collects fees while it fills. Only trades that pass through the one-tick range pay the pool's fee tier to the position; a listing waiting below its ask collects nothing.
collectFees(id)swaps those fees to ETH and adds them to the pot. - It is public. Each listing is an NFT position on the Uniswap V3 position manager, owned by the machine. The board links every one.
05Who can call what
| Function | Who | What it does |
|---|---|---|
harvest() | Anyone | Sweep + claim Pons creator fees, split 85 / 10 / 5 |
buy(minUsdgOut, minStockOut) | Keeper any time; anyone when pot ≥ 0.05 ETH and 6 h passed since the last buy | Pot → USDG → next stock, TWAP-checked, then lists it at +50% |
settle(id, minTokensOut) | Anyone, once the listing is filled | USDG out → ETH → buy $MARKUP → burn |
burnNow(minTokensOut) | Keeper; anyone after the public delay | Burn bucket ETH → buy $MARKUP → burn |
collectFees(id) | Anyone | Swap fees of a live listing → ETH → pot |
| Admin functions | Owner (two-step ownership) | Only the limited changes in Admin limits |
The keeper is a bot run by the team that harvests, buys and settles on a schedule with quoted minimums. It has no extra power over funds: everything it does, anyone can do after the delay. The board has Harvest, Settle and Burn now buttons for any wallet.
06Admin limits
The owner can make a short list of changes, and each one only moves in one direction:
raiseMarkup: the markup can go up only (never below +10%, starts at +50%).raiseBurn: the burn share can go up only, taken from the dev share first, then the pot.lowerDev: the dev share can go down only. Changing the dev address is two-step (propose, accept).queueStock→addStock: a new stock can be added only after a 48 h public timelock (theStockQueuedevent shows it).pauseStockstops buying a stock; existing listings are untouched.setBuyConfig: minimum buy, TWAP window, deviation and public delay, within fixed bounds (TWAP ≥ 10 min, deviation ≤ 3%).setKeeper: rotate the keeper.
delegatecall.- Cancelling a listing is timelocked and stays inside the machine. The owner can call
queueCancel(id); after a public 48 h wait (CancelQueuedevent)cancelListing(id)pulls the position out. The stock goes back into the machine'sdustStockand is re-listed with the next buy of that stock; any USDG the listing already sold for goes to the burn bucket. Nothing is sent to the owner.
07Risks
- Stock tokens follow the stock. Robinhood stock tokens track real shares. They can fall, trade thinly outside market hours, and their pools can have little liquidity. A big move can happen while the US market is closed.
- Un-fill. A listing that crosses the ask can turn back into stock if the price falls before
settle()is called. - TWAP guard. Buys check spot against a 30-minute average. A TWAP can still be pushed in a thin pool, and a fast real move can make buys wait until the average catches up.
- Pons owner override. The Pons V2 owner can change any coin's fee recipient, including the machine, after a 3-day public timelock. The machine cannot remove this Pons-level power.
- Burn slippage. Burns buy $MARKUP on the open market. Every burn needs a minimum output (zero is rejected); the board sets it at 3% under an exact on-chain quote, and public burns open only 6 h after the last burn, so a sale settled by someone else waits in the burn bucket for the keeper.
- Stock token controls. Robinhood stock tokens are upgradeable contracts that can pause transfers, block addresses and burn balances (
adminBurn). If that is used on the machine or a pool, listed stock can be frozen or removed. The machine cannot prevent it. - Unaudited. The contracts are tested against a fork of Robinhood Chain but not externally audited. Bugs are possible.
- No promise of price. Burns depend on trading volume and on stocks reaching their asks. No volume, no fees; no sale, no sale burn.
Not financial advice. Unaudited contracts. Stock tokens are Robinhood stock tokens; the machine holds them, nobody else does.
08Contracts
Robinhood Chain mainnet, chain id 4663. Read live from contracts.json and token.json.
| Contract | Address |
|---|---|
09$MARKUP
$MARKUP launches on Pons V2 with the machine as its creator fee recipient from the launch transaction. That is the whole token design: trading pays fees, fees run the machine, the machine burns $MARKUP.
| Launch | |
| Contract | |
| Where | Pons launchpad |
The only official contract address is the one shown on this site and pinned on our X and Telegram.
10FAQ
Does the machine pay holders?
No. The machine buys stocks, lists them, and burns $MARKUP with what sells. It sends nothing to holders and makes no promise about the price of $MARKUP.
Why NVDA and TSLA?
They are official Robinhood stock tokens on Robinhood Chain with Uniswap V3 pools against USDG that are deep enough for the machine's buys and have a usable 30-minute price history. More stocks can only be added through the 48 h timelock.
What if a stock never goes up 50%?
Then that listing waits, possibly forever. The machine keeps buying with new fees and lists each purchase separately, so one stuck listing does not stop the next one.
Who holds the stock tokens?
The machine contract, inside its Uniswap V3 positions. Nobody else holds them and nobody can withdraw them.
Can I press the buttons on the board?
Yes. Harvest, Settle (on a filled listing) and Burn now work from any wallet on Robinhood Chain. You pay the gas; the machine does not pay you.
Why is the board in preview?
The machine contract deploys at launch. Until then the board shows live NVDA and TSLA prices and what the first listing would look like.
Is this affiliated with Robinhood, NVIDIA, Tesla or Pons?
No. Markup Machine is an independent contract that uses public Robinhood stock tokens and public pools on Robinhood Chain.