Six claims, and the test that holds each
The tests are named after the promises rather than after the functions, so a failure says which promise broke. What follows is their own output.
Claim 01
Withdrawals are never pausable.
The guardian can stop deposits and stop harvests. It cannot stop anyone leaving. A pause that traps depositors is indistinguishable from a rug, so the power to do it is not in the contract.
=== the guardian can stop deposits and cannot trap anyone ===
ok a stranger cannot pause AccessControlUnauthorizedAccount(0x626f62…, 0x5543…)
ok the guardian can
ok maxDeposit goes to zero while paused 0 vs 0
ok deposits are refused while paused ERC4626ExceededMaxDeposit(0x626f62…, 1000000000, 0)
ok but a paused vault still lets every depositor out, in full 10000000000 vs 10000000000
ok the guardian cannot unpause — it can only ever stop things
ok the admin can
Claim 02
A dead oracle stops money coming in, never money going out.
Exiting is priced off the vault's own balance, not off a feed, so a stale feed must not become a lock.
=== a dead oracle stops money coming in, never money going out ===
ok a stale feed refuses the deposit StalePrice(10800, 3600)
ok and still lets the money out, in full 10000000000 vs 10000000000
ok a harvest against a stale feed is refused too StalePrice(10800, 3600)
Claim 03
The fee split is 70 / 20 / 10, and the 70 is the share price.
The compounded share is not sent anywhere. It stays in the vault, which raises what the same shares are worth. That is the entire mechanism the home page draws.
=== the fee split is 70 / 20 / 10, and the 70 is the share price ===
ok 20% goes to the buyback 200000000 vs 200000000
ok 10% goes to the treasury 100000000 vs 100000000
ok 70% is left in the vault 700000000 vs 700000000
ok the vault holds the deposit plus the compounded fees 10700000000 vs 10700000000
ok no new shares were minted 10000000000000 vs 10000000000000
ok so the same shares are now worth more 10699999999 vs 10700000000
ok and the depositor can take the gain out 10699999999 vs 10700000000
Claim 04
Rounding never pays out more than was put in.
Eight deposit sizes chosen so every conversion has something to round, against a share price deliberately left irrational. One wei the depositor's way, repeated, is how a vault is drained.
=== rounding never pays out more than was put in ===
ok 7 in: redeem pays exactly what previewRedeem quoted 6 vs 6
ok 7 in: the round trip never ends ahead net -1 wei
ok 12345 in: the round trip never ends ahead net -1 wei
ok 77777000013 in: the round trip never ends ahead net -1 wei
ok 8 sizes exercised
ok and the most a round trip costs in rounding is a wei or two worst: 1 wei
ok and every one of them closed clean 0 vs 0
Claim 05
The oracle prices the position. The pool only executes.
This is the one that matters. A pool's spot price is whatever the previous line of the same transaction left behind, and a flash loan can leave behind anything. Vaults that priced themselves off spot are the single most repeated way this shape of contract has been emptied. Below, an attacker moves a real Uniswap pool 8.6% and the valuation does not shift one wei — then the oracle moves, and it does.
=== the oracle prices it, the pool only executes ===
ok the attacker can move the pool at will
ok and really did move it tick -222404 -> -241492
ok yet totalAssets did not move one wei 99833208648 on both sides
ok the attacker can shove it the other way too
ok and that does nothing either tick now -219964
ok but a real oracle move does reprice it 99833208648 -> 117501212582
ok and it comes back when the oracle does
Claim 06
No swap runs unbounded.
Every swap carries a price limit taken from the oracle and is measured again afterwards against what the oracle said it should have fetched. One-sided on purpose: buying below the oracle price is not a loss to defend against — whoever moved the pool paid for that discount.
=== no swap runs unbounded ===
the attacker walked the pool from tick -222408 to -206787; the oracle has not moved
ok a deposit into a pool walked away from the oracle is refused, not executed
ok and refused in the strategy's own words PoolDislocated(2563276…, 1173646…)
ok a pool that has moved in the vault's favour is not refused
ok and the vault keeps the discount +240429 USDG for 50,000 in
ok and the admin cannot widen the guard past 5% BadSlippage()
The Uniswap maths is Uniswap's, and proved to be
Uniswap caps TickMath below Solidity 0.8 because it leans on arithmetic that wraps. Moving it forward is mechanical, but “it compiles” is not evidence that a port is right, so it is checked twice: against the exact value computed in another language, and against Uniswap's own build.
Libraries
Matching an independent value proves the maths. Matching the original proves the transcription.
The strategy's tests then run against Uniswap's shipped pool bytecode, deployed by Uniswap's own factory. A mock of a pool would only ever prove that the strategy agrees with our idea of Uniswap.
=== tick -> sqrtPrice, against 431 independently computed values ===
ok every tick lands on the independently computed value, to the wei worst gap 1 wei at tick -887272
=== against Uniswap's own build (0.7.6+commit.7338295f) ===
ok 431 ticks give byte-identical answers to Uniswap's build
ok and 430 inverses do too
ok 1066 comparisons, every one identical to Uniswap's
ok all three price branches were exercised below 26, inside 39, above 26
=== a full round trip through a real pool ===
ok exactly half is swapped into the Stock Token, as the page says 50000 of 100000
ok a full round trip costs only the pool fee and the spread 99700 USDG of 100,000 — 0.29% lost
What is not built
Stated at the same size as the rest, because a proof page that only lists what works is an advertisement.
- Not deployedNothing is on any chain.No mainnet, no testnet, no addresses. Every contract address shown elsewhere on this site is a placeholder, and is labelled as one.
- Not auditedNo external review has happened.The tests below are written by the same hand as the contracts, which is worth exactly what that is worth. An audit is what catches what the author could not see.
- Not wiredThe vault and the strategy do not yet talk to each other.Each is tested on its own. Joining them means a withdrawal has to pull liquidity from the position when the idle balance will not cover it — the path every withdrawal takes.
- Known gapFees earned since the last collect are not counted.Reading them needs a state-changing poke, so totalAssets understates the vault. Safe against theft, slightly unfair to existing holders, and marked in the source.
- Known gapA dislocated pool stalls deposits.If the pool drifts further from the oracle than the slippage bound, deposits and rebalances revert rather than execute. Refusing is the safe behaviour, but a violent move can stall the vault until someone arbitrages it back.
- Not solvedThe tokenized equities question is not a contract problem.The Stock Tokens these vaults would hold are issued by regulated entities with transfer restrictions. No amount of Solidity answers that, and it is the longest pole of the lot.
Run it yourself
The suite needs no network and no keys. It compiles the contracts and executes them on an in-process EVM.
# in the contracts directory
npm install
npm run build # solc 0.8.28, pinned
npm test # 131 assertions