SatoToken

plain erc-20 with one privileged role: a mint authority that locks itself permanently after a single call.

SatoTokenis the erc-20 itself. it inherits from openzeppelin's standard ERC20 and adds exactly four things on top: an immutable deployer, an immutable genesis fingerprint pair, a single one-shot minter setter, and a marker constant denying any restriction primitives. nothing else.

the entire contract is < 80 lines of solidity. it does not run any custom logic during transfers, holds no eth, has no admin role beyond the one-time minter assignment, and offers no upgrade path.

state

minter
the only address allowed to call mint or burn. starts as address(0); once set via setMinter, never changes.
DEPLOYER
immutable. set in the constructor from msg.sender. only this address can call setMinter.
GENESIS_BLOCK
immutable. set to block.number at deployment.
GENESIS_HASH
immutable. set to blockhash(block.number − 1) at deployment. the only way to fabricate one is to deploy at that block.
RESTRICTIONS_FORBIDDEN
immutable bool, set to true. purely declarative — a self-evident on-chain assertion that this contract implements no pause, no blocklist, no allowlist, no transfer hooks beyond standard erc-20.

functions

setMinter(address)
callable exactly once, by DEPLOYER only. reverts with NotDeployer, MinterAlreadySet, or MinterIsZero. emits MinterLocked(minter).
mint(to, amount)
callable only by the locked-in minter (the hook). reverts with NotMinter. used to credit buyers.
burn(from, amount)
callable only by the locked-in minter. reverts with NotMinter. used to retire sellers' tokens during sell settlement.

events and errors

  • event MinterLocked(address indexed minter)— fires exactly once, at the moment the minter is permanently assigned.
  • error NotDeployer(), NotMinter(), MinterAlreadySet(), MinterIsZero() — the only four named errors. no other paths revert with custom errors.

what is not in this contract

  • no owner, no Ownable.
  • no pause, no Pausable.
  • no blacklist, no blocklist, no allowlist.
  • no transfer fees, no rebasing, no reflection.
  • no upgrade proxy, no fallback function, no selfdestruct.
  • no signature-based meta transactions (no permit).

the deployment sequence

the only privileged action the deployer ever takes is the single setMinter call. the canonical sequence is:

  • 1. deploy SatoToken. the deployer becomes DEPLOYER; minter remains address(0).
  • 2. deploy SatoHook, passing the token's address into its constructor.
  • 3. call SatoToken.setMinter(hookAddress). this is the one and only privileged call. MinterLocked fires; from this moment, even the deployer has no special powers over the token.

after step 3, the DEPLOYERaddress still exists on the contract but every function it could call now reverts. it's a cryptographic vestige.

this page describes deployed code. nothing here is a promise — it is a description of what the contract does and what it doesn't.