Security and trust
Who can do what
| Action | Who |
|---|---|
| Set the DOME mint and burn market | the program's upgrade authority, once (init_config) |
| Open a pool | anyone |
| Swap, deposit, withdraw, collect | anyone, for their own positions |
| Convert fees and burn DOME | anyone |
| Pause, delist, move pool funds, change fees | nobody: there is no instruction for it |
Fees, bands and size caps are compile-time constants in constants.rs. No account stores them, so no signer can change them.
Solvency check on every move
After every swap, deposit, withdrawal and fee payment the program checks that each vault holds at least what the pool owes for that coin:
reserves[k] + protocol_fees[k] + lp_fees_pending[k] <= vault balance
If not, the transaction fails with Insolvent.
Rounding favours the pool
- Swap fee: rounded up.
- Deposits: the amount you pay for a given radius is rounded up.
- Withdrawals and fee payouts: rounded down.
A sequence of small trades can therefore never pull value out of the pool through rounding.
Depeg isolation
A band only absorbs a falling coin until its edge. After that it is pinned: it holds no more of that coin and trades only the others. The worst a depeg can do to a band is set by the price the band chose. A full band (band 7) has no edge and covers every price, so it carries the most depeg risk and needs the most capital.
The engine's depeg test sells USDC into a four-coin pool until it prices USDC at $0.90:
| Band | Healthy coins paid out | Its limit |
|---|---|---|
| $0.998 | $998,748 | $998,749 |
| $0.99 | $1,992,460 | $1,992,462 |
| $0.95 | $1,973,971 | $1,973,973 |
Each band pays out up to its own edge and not a dollar more. The healthy coins keep trading, with less depth: pinned tight bands have small rims, so the wide bands carry most of the trading until the peg returns. In the same scenario with $40M of liquidity, DOME's liquidity providers lose $1.83M against $2.65M in one Curve-style pool (A = 200).
Hostile mints
Token-2022 mints with a transfer hook, a transfer fee or the non-transferable extension are refused at create_pool. The vault balance check also catches any mint that delivers less than it was asked to (InputShortfall).
The burn cannot be drained
convert_feestrades only the protocol's share, through the pool itself, and must return at least 99.5% of the input (CONVERT_MIN_OUT_PPM), so tilting the pool first does not pay.buy_and_burnspends at most 0.1% of the Raydium pool's reserve per call (BURN_MAX_RESERVE_BPS) and must get at least 98% of the 30-minute time-weighted price (BURN_MIN_OUT_BPS,BURN_TWAP_SECS). Every token bought is burned in the same instruction.
No oracle
Swap prices come from the reserves alone. There is no price feed to stall or manipulate.
Next: Economics