The coin
Every Divvy coin is a clone (EIP-1167) of one small contract, DivvyCoin. It is an ordinary ERC-20 with 18 decimals and a fixed supply of 1,000,000,000, all of which starts inside the coin itself. The coin is also its own market: a constant-product curve between the coins it holds and a reserve of ETH that starts with a virtual 1 ETH. So a new coin has a price from its first block (a market cap of 1 ETH), and there is no other pool to route around its fee.
Buying sends ETH in; the fee is taken first, the rest goes to the curve, and you receive coinReserve × net ÷ (ethReserve + net) coins, rounded down. Selling is the mirror image, and the fee is taken from the ETH that comes out. The page computes both with the contract’s own integer formulas and sends a minimum 1% below its quote.
The fee
Chosen at launch, from 0.25% to 10% in steps of 0.25%, and stored in the coin. No function changes it: there is no owner and no admin, in the coin or in the factory. Every buy and every sell pays it, in ETH. None of it goes to the creator or to Divvy: all of it becomes stock for the holders.
How the stock is shared
Each fee is swapped into the coin’s stock (below) and shared out at once, by a running total: stockPerCoin grows by stock bought ÷ coins in wallets, and what a wallet is owed is its balance times how much that total has grown since the wallet last moved. “Coins in wallets” means every coin not inside the coin’s own curve (circulating()), so the curve earns nothing and the whole fee goes to real holders.
The coins in a trade never earn from that trade’s fee. A buy’s fee is shared before the buyer’s new coins arrive; a sell’s after the sold coins have gone back to the curve. (Coins the trader already held, and still holds, earn their share like anyone else’s.) When coins move (a transfer, a buy, a sell), both wallets are settled at their old balances first, so what the coins earned before the move stays with whoever held them, and only what comes after follows the coins.
Rounding never lets the coin owe more than it holds. The share per coin is rounded down; the amount set aside for it is rounded up, and the difference (at most one unit of stock) is carried into the next share-out, as is stock bought while no one holds a coin at all (the launcher’s own first buy, for example). The tests hold the contract to a model written separately and to one inequality after every step of a random sequence: every unit the coin holds is owed to somebody or carried, and never less.
Claiming
claim(to) sends everything the caller is owed to to, in the stock, and touches nothing else: the coins stay where they are, and the next trade starts paying again. There is no deadline and nothing expires. A wallet that has sold every coin can still claim what it earned. Your payouts reads every coin at once and shows what is waiting.
One thing to know: stock is shared with every address that holds the coin, including a contract. If someone sends coins to a contract that cannot call claim, that contract’s share waits there forever. The coin’s own market is the curve inside it, so nothing is lost this way unless someone chooses to.
The fair-price guard
Each fee is swapped inside the same transaction: ETH → USDG in Uniswap’s WETH/USDG 0.01% pool, then USDG → the coin’s stock in its pool (the fee tier chosen at launch; the launch page picks the deepest). Before swapping, the coin reads both pools’ time-weighted average price (30 minutes; if a very busy pool has overwritten that much history, 10 minutes, then 2) and sets the swap’s minimum to what the averages say the ETH is worth, less both pools’ fees and 2%.
A price pushed inside the current block carries no weight in an average, so an attacker who moves a pool and then triggers a purchase gets nothing: the swap fails its minimum, the ETH stays in the coin as pendingEth, and the next trade (or anyone calling convert) tries again. The trade itself always goes through.
One refusal is deliberate: a transaction with too little gas left for the swap reverts with NeedsMoreGas instead of quietly deferring the fee. Wallets estimate the smallest gas at which a transaction does not revert; without that refusal, estimates would starve every purchase.
The picture and links
The picture (cropped square and shrunk to under 16 KB in your browser), the description and up to three links are ABI-encoded and stored as the code of a tiny contract (SSTORE2) when the coin launches: 24 KB at most. meta() returns them byte for byte. Nothing depends on a server.
The contracts
| What | Address |
|---|---|
| DivvyFactory | 0xcea82e8d755101c4CD3AD584f7588a9917f2f01d |
| DivvyCoin implementation | 0x437Ac6AD7fB324c20a98B9aA9c2A64010cAB8d40 |
| CREATE2 deployer (Arachnid’s, deterministic) | 0x4e59b44847b379578588920ca78fbf26c0b4956c |
| Uniswap SwapRouter02 | 0xCaf681a66D020601342297493863E78C959E5cb2 |
| WETH / USDG 0.01% pool | 0x52e65B17fB6E5BA00Ed806f37Afcd2DaA50271Ca |
The factory’s address is keccak256(0xff ++ deployer ++ salt ++ keccak256(initCode)), with salt 0xb61d64ae899aefb12abfbbc5b5e79b7b28bb1ff7e65533b98a3aafd9f8a3e189 and init-code hash 0x883b380cad840b11a3e2ce29d312cc1d35ac5aa06c4ef883e362e7d7d586a2af. So the address is the code: anyone can deploy it, and whoever does puts exactly this code there. The launch page does it for you: if the factory is not there yet, your wallet first sends that one deployment, then your launch. Source: DivvyFactory.sol, DivvyCoin.sol, and Uniswap’s TickMath.sol; solc 0.8.26, optimizer 1000 runs, via-IR, Cancun. Status right now: checking…
How it was tested
Every property below runs on a private fork of live Robinhood Chain (anvil, started fresh at the newest block for each property): the real CREATE2 deployer deploys the factory, coins launch on real stock tokens, and every purchase swaps through the real Uniswap pools, in the state they are in right now. Nothing is broadcast and nothing is mocked. Expected numbers are computed in the test from the formulas written out there, never by asking the contract; the share-out is checked against a model that knows nothing of the contract’s running total.
The last run: 11/11 properties and 772 checks passed against live state (30 Sep 2026), for the factory at 0xcea82e8d755101c4CD3AD584f7588a9917f2f01d.
| # | Property | Checks |
|---|---|---|
| P1 | The factory lands at the address its code fixes, with the implementation beside it | 7 |
| P2 | Launch refuses every bad input with the error named for it, and accepts a good one | 21 |
| P3 | Buys and sells pay exactly the curve and the fee, and every fee becomes stock or waits | 63 |
| P4 | A round trip never makes money in ETH, and everyone can always sell back | 22 |
| P5 | Stock is only bought near the average price; a pushed pool defers the buy until it is not | 16 |
| P6 | The price read is Uniswap's, in both token orders and every fee tier, and the swap matches the quoter NVDA through its 0.05% pool: 0.005 ETH bought 0.058422 NVDA, 16 bp below the 30-minute average (the floor allows 206 bp below) SPCX through its 0.05% pool: 0.005 ETH bought 0.089053 SPCX, 15 bp below the 30-minute average (the floor allows 206 bp below) TSLA through its 0.3% pool: 0.005 ETH bought 0.037788 TSLA, 39 bp below the 30-minute average (the floor allows 231 bp below) MSTR through its 1% pool: 0.005 ETH bought 0.086599 MSTR, 108 bp below the 30-minute average (the floor allows 301 bp below) | 17 |
| P7 | Stock is divided by what each wallet holds, never to the coins being traded, and claims pay it exactly | 60 |
| P8 | Too little gas is refused outright rather than silently deferring the fee | 8 |
| P9 | A coin keeps its picture and links on chain, byte for byte | 6 |
| P10 | The coin is an ordinary ERC-20, refuses stray ETH, and cannot be re-initialised | 10 |
| P11 | Under random trading, every holder is owed what the model says and the coin can always pay everyone 26 random steps + coda; landed 21 buy, 4 sell, 3 transfer, 6 claim, 25 stockBuy | 542 |
Then a sabotage sweep plants 22 bugs, one at a time, in copies of the contracts: the fair-price guard removed, the 30-minute average swapped for the spot price, a buyer paid out of their own fee, a transfer that carries past earnings with the coins, the curve counted as a holder, a claim that can be taken twice, stock bought while nobody held a coin thrown away, the set-aside rounded down so the coin can owe more than it holds. It requires the property named for each one to fail. 22/22 were caught by the property named for them.
And in a real browser: headless Chrome drove these pages with a test wallet against a private copy of the live chain. One click on the launch page deployed the factory and launched a coin with a picture, paying in NVDA; a second wallet bought, and the launcher’s payout appeared on its coin page; the launcher claimed it from the button and exactly that NVDA arrived in its wallet; then a buy and a sale through the trade box, a claim from the payouts page, and the board. 7/7 journeys, 35 checks, each outcome read back from the chain by the harness itself (30 Sep 2026).
Risks
- Unaudited. The contracts are small and tested, not audited.
- Coins can go to zero. A Divvy coin has no floor: its payouts are paid as they happen, not kept as backing. What you have been paid is yours; what the coin is worth is up to the market.
- Payouts depend on trading. No trades, no fees, no stock. The calculator on the front page is arithmetic, not a forecast.
- Stocks fall, and Robinhood controls its stock tokens. Robinhood can pause, block or burn its tokenized stocks. A paused stock cannot be bought (fees wait as ETH) or claimed (claims revert until it resumes).
- Thin pools make fees wait. If the stock’s pool is too thin for a fair fill, the fee waits as ETH until a trade or
convertcan buy at a fair price.