reading the source
the contracts are short. here is how to navigate them, what each file is responsible for, and how to verify the deployment matches.
the entire protocol is three solidity files. this page describes where each lives, what each holds, and how to confirm that what is on chain is exactly what the source says.
repo layout
SatoToken.sol- ~80 lines. one openzeppelin
ERC20inheritance, onesetMinter, onemint, oneburn, four custom errors. no other logic. SatoHook.sol- ~450 lines. fourteen hook permission entry points (four of which do real work), the buy and sell paths, the entropy multiplier, the cooldown, and a manifesto getter. all guardrails and reverts live here.
lib/Curve.sol- ~120 lines.
totalMinted,mintFor,burnFor,marginalPrice,ethAt, plus fourUD60x18helpers and two custom errors. pure functions, no state.
dependencies
- v4-core — uniswap's singleton
PoolManagerand hook interfaces. vendored at a specific commit; never modified. - openzeppelin-contracts — the standard
ERC20.SatoTokenoverrides nothing; it uses it as-is. - prb-math —
UD60x18fixed-point withexpandln. the curve library uses only these two functions plus its own thin wrappers around arithmetic.
verifying a deployment
the source compiles deterministically under compiler_config.json. given the address of a deployed contract you can verify it has the expected bytecode by comparing hashes:
# 1. clone the source at the deployment commit git clone <repo> sat0 && cd sat0 git checkout <deployment-tag> # 2. compile with the locked config solc --standard-json < compiler_config.json > out.json # 3. hash the deployed runtime bytecode cast code <SatoHook-address> | keccak # 4. hash the compiled runtime jq -r '.contracts."src/SatoHook.sol".SatoHook.evm.deployedBytecode.object' out.json \ | keccak # the two hashes must match
on top of bytecode equivalence, a deployment can be tied to a specific point in chain history with GENESIS_BLOCK and GENESIS_HASH— both immutable, both readable via single eth_calls.
reading order
if you want to read the contracts in the order that makes them easiest to follow:
- 1.
lib/Curve.sol— the math first. pure functions, no surprises. - 2.
SatoToken.sol— the trivial erc-20 surrounding the locked minter. - 3.
SatoHook.sol, top to bottom — the implementation note, then the constants and immutables, thenbeforeSwapand its two internal helpers_executeBuyand_executeSell. the unused hook entry points sit at the bottom; skip them on a first pass.
what to grep for
revert- ten total in
SatoHook.sol, three inSatoToken.sol, two inCurve.sol. each is named; reading them tells you every failure mode. immutable- tells you which values are set at construction and never change. the token has four, the hook has six.
public constant- everything else baked into bytecode:
K_SUPPLY,S,MAX_BUY_WEI,COOLDOWN_BLOCKS,POOL_FEE,ENTROPY_BLOCKS,EXHAUSTION_*. onlyPoolManager- every entry point on the hook. the only address with the ability to call those entry points is the v4
PoolManager.
this page describes deployed code. nothing here is a promise — it is a description of what the contract does and what it doesn't.
