The SATO ERC-20 contract is the token accounting layer of the SATO protocol.
It is intentionally implemented as a minimal ERC-20 contract with one designated protocol minter. That minter is assigned once and cannot be changed after initialization.
The contract does not implement ownership, pausing, blacklisting, whitelisting, transfer taxation, upgradeability, or arbitrary administrative controls.
Monetary policy, reserve accounting, bonding curve execution, and swap behavior are implemented outside the ERC-20 contract by the protocol execution layer.
| Property | Value |
|---|---|
| Network | Ethereum Mainnet |
| Contract | 0x829f4B62EEBE12Af653b4dD4fFc480966F7d7f09 |
| Contract name | SatoToken |
| Token name | sato |
| Token symbol | sato |
| Decimals | 18 |
| Compiler | Solidity 0.8.26 |
| Verification | Etherscan source code verified, exact match |
| Locked minter | 0x0000f07d2B5F1Ddf3244b8780F972f306EFd2888 |
The locked minter is the deployed SatoHook protocol contract.
contract SatoToken is ERC20The contract inherits from OpenZeppelin's ERC-20 implementation and adds only the minimal protocol-specific authorization required for minting and burning.
The token is constructed with:
ERC20("sato", "sato")There are no constructor arguments.
The ERC-20 contract follows a minimal accounting model.
It intentionally avoids discretionary administrative mechanics commonly found in token contracts, including owner-controlled upgrades, pause mechanisms, blacklists, whitelists, transfer taxes, fee logic, and administrative balance controls.
This design keeps the token contract focused on accounting while delegating monetary behavior to the protocol execution layer.
The ERC-20 contract is responsible for:
- token balances
- transfers
- allowances
- total supply accounting
- protocol-authorized mint execution
- protocol-authorized burn execution
The ERC-20 contract is not responsible for:
- bonding curve calculations
- ETH reserve accounting
- swap execution
- protocol pricing
- fee accounting
- liquidity management
- governance
- treasury management
| Variable | Type | Purpose |
|---|---|---|
minter |
address |
Stores the designated protocol minter. |
DEPLOYER |
immutable address |
Stores the deployment address that may call setMinter() once. |
RESTRICTIONS_FORBIDDEN |
immutable bool |
Marker indicating that the contract does not use restriction primitives. |
GENESIS_BLOCK |
immutable uint256 |
Stores the deployment block number. |
GENESIS_HASH |
immutable bytes32 |
Stores the hash of the block immediately preceding deployment. |
Only minter is mutable.
Once minter is set, it cannot be changed.
During construction, the contract records:
DEPLOYER = msg.sender;
GENESIS_BLOCK = block.number;
GENESIS_HASH = blockhash(block.number - 1);These values are immutable and permanently embedded into the contract state.
They provide deployment metadata without creating ongoing administrative authority.
The contract includes the following immutable marker:
bool public immutable RESTRICTIONS_FORBIDDEN = true;This marker documents the intentional absence of restriction primitives.
The ERC-20 contract does not implement blacklists, whitelists, account freezing, transfer blocking, pause controls, or administrative transfer restrictions.
The minter is assigned through:
function setMinter(address newMinter) externalThis function may only be called by DEPLOYER.
It may only be called once.
It rejects the zero address.
After the minter has been assigned, any later attempt to change it reverts.
This creates a permanent link between the ERC-20 accounting layer and the protocol execution layer.
The contract uses a narrow access-control model.
There is no owner role.
There is no administrator role.
There is no governance role.
The only privileged operation is protocol mint and burn authorization, and it is restricted to the locked minter.
This model is intentionally narrower than conventional owner-based token administration.
Initializes the token.
Responsibilities:
- sets token name to
sato - sets token symbol to
sato - records deployer address
- records deployment block
- records previous block hash
The constructor does not mint initial supply.
The constructor does not allocate tokens to a treasury, team, foundation, or deployer.
Locks the protocol minter.
Validation:
- caller must be
DEPLOYER mintermust not already be setnewMintermust not be the zero address
Effects:
- stores
newMinterasminter - emits
MinterLocked(newMinter)
This function is a one-time initialization function, not an ongoing administrative control.
Creates SATO tokens.
Validation:
- caller must be the locked
minter
Effects:
- calls OpenZeppelin
_mint(to, amount)
Purpose:
- executes protocol-authorized token issuance
- used by the protocol layer during valid buy-side execution
The ERC-20 contract does not decide when minting should occur.
Destroys SATO tokens held by from.
Validation:
- caller must be the locked
minter
Effects:
- calls OpenZeppelin
_burn(from, amount)
Purpose:
- executes protocol-authorized token retirement
- used by the protocol layer during sell-side redemption
This function is not a general administrative balance-editing mechanism.
Emitted when the protocol minter is permanently assigned.
This event provides an on-chain record of when ERC-20 mint and burn authorization becomes linked to the protocol execution layer.
The contract uses custom errors instead of string reverts.
| Error | Trigger |
|---|---|
NotDeployer() |
Caller other than DEPLOYER attempts to set the minter. |
NotMinter() |
Caller other than minter attempts to mint or burn. |
MinterAlreadySet() |
setMinter() is called after the minter has already been assigned. |
MinterIsZero() |
setMinter() is called with the zero address. |
The locked minter is the SatoHook protocol contract.
SatoHook acts as the monetary execution layer of the protocol.
The ERC-20 contract acts as the accounting layer.
During buy-side execution, SatoHook calls mint() to execute protocol-authorized issuance.
During sell-side execution, SatoHook calls burn() to execute protocol-authorized token retirement.
This architecture separates token accounting from monetary policy.
The ERC-20 contract intentionally omits discretionary administrative features.
It contains:
- no owner
- no proxy
- no upgrade path
- no pause function
- no blacklist
- no whitelist
- no transfer tax
- no arbitrary balance modification function
The existence of mint() and burn() should be evaluated in the context of the locked minter model.
Only the permanently assigned protocol contract may call these functions.
Automated token scanners may detect the presence of mint and burn functions and classify them as privileged balance-changing functionality.
In SATO, this interpretation is incomplete.
Minting and burning are not controlled by an owner wallet.
They are restricted to the locked SatoHook contract and are used as part of deterministic protocol execution.
Additional analysis is provided in:
docs/security/05_False_Positive_Analysis.md
The token remains compatible with standard ERC-20 infrastructure.
Supported behavior includes:
- transfers
- approvals
- allowances
- balance queries
- total supply queries
Protocol-specific behavior affects only minting and burning, which are restricted to the locked protocol minter.
The SATO ERC-20 contract is intentionally minimal.
It does not implement monetary policy, reserve accounting, pricing, liquidity management, or governance.
Its role is to maintain ERC-20 token accounting while allowing the locked protocol contract to execute valid mint and burn state transitions.
This separation of concerns keeps the token contract simple, transparent, and compatible with Ethereum infrastructure.
This document is not an audit. It summarizes the verified ERC-20 contract design and should be read together with the deployed source code.