Smart contracts for the Yellow Network. Node operators post YELLOW tokens as a mandatory functional security deposit in the NodeRegistry to operate clearnode infrastructure. App builders post YELLOW in the AppRegistry as a service quality guarantee. The Treasury is managed directly by the Layer-3 Foundation.
Node operators post YELLOW --> NodeRegistry (IVotes) --> YellowGovernor --> TimelockController
collateral weight proposals delayed execution
App builders post YELLOW ----> AppRegistry (ISlash)
collateral + slashing
Foundation ------------------> Treasury
Foundation assets
ERC-20 utility token with EIP-2612 permit support. Fixed supply of 10 billion YELLOW minted entirely to a treasury address at deployment. No mint or burn functions.
Node operator registry. Operators post YELLOW tokens as a mandatory functional security deposit and receive collateral weight via the OpenZeppelin Votes interface (IVotes). Locked balances serve as collateral weight for protocol parameter administration with on-chain checkpointing.
State machine per user:
lock(amount) unlock() withdraw()
Idle ----------------> Locked ----------------> Unlocking ----------------> Idle
| |
lock(amount) top-up relock()
(stays Locked) (returns to Locked)
lock(amount)-- deposit tokens into the vault. Can top up while Locked.unlock()-- start the withdrawal countdown (configurable at deployment). Collateral weight is removed.withdraw()-- after the unlock period elapses, claim the full balance.relock()-- cancel an in-progress unlock and restore collateral weight.delegate(address)-- delegate collateral weight. Users must calldelegate(self)to activate their own weight.
Registry for app builders who post YELLOW as a service quality guarantee. Implements the same lock/unlock/withdraw state machine as NodeRegistry but without collateral weight. An adjudicator can slash a participant's balance in both Locked and Unlocking states as penalty for misbehaviour.
slash(user, amount, recipient, decision)-- callable only by an address withADJUDICATOR_ROLE. Reduces the user's balance and transfers slashed tokens to the recipient.- Full slash resets the user's state to Idle.
- Slash cooldown -- a global cooldown can be set by the admin (
DEFAULT_ADMIN_ROLE) viasetSlashCooldown(seconds)to rate-limit slashing. This prevents a rogue adjudicator from batch-draining all users in a single transaction, giving the admin time to revoke the role. Set to0to disable (default).
OpenZeppelin Governor for protocol parameter administration with the following extensions:
| Extension | Purpose |
|---|---|
| GovernorSettings | Configurable consensus delay, period, and proposal threshold |
| GovernorCountingSimple | For / Against / Abstain signalling |
| GovernorVotes | Reads collateral weight from the NodeRegistry |
| GovernorVotesQuorumFraction | Quorum as percentage of total locked supply |
| GovernorTimelockControl | Routes execution through TimelockController |
Proposal lifecycle: Propose --> Signal (after consensus delay) --> Queue (if passed) --> Execute (after timelock delay)
OpenZeppelin TimelockController. Enforces a delay between proposal approval and execution, giving participants time to react. The Governor holds the proposer and canceller roles. Execution is open (anyone can trigger after the delay).
Secure vault for Layer-3 Foundation assets, supporting ETH and ERC-20 transfers. Owned directly by the Foundation address via Ownable2Step.
transfer(token, to, amount)-- moves funds out of the treasury. Useaddress(0)for ETH.
The @yellow-org/contracts npm package exports typed ABIs and deployed addresses for use with viem, ethers.js, and wagmi. See sdk/README.md for usage.
npm install @yellow-org/contractsgit clone <repo-url>
cd yellow
forge installforge buildforge testforge fmt| Contract | Address |
|---|---|
| YellowToken | 0x236eB848C95b231299B4AA9f56c73D6893462720 |
| Contract | Address |
|---|---|
| YellowToken | 0x236eB848C95b231299B4AA9f56c73D6893462720 |
| Faucet | 0x914abaDC0e36e03f29e4F1516951125c774dBAc8 |
Deployment is split into separate scripts, each with its own bash wrapper that loads configuration from .env:
| Script | Bash | Purpose |
|---|---|---|
DeployToken.s.sol |
deploy-token.sh |
Deploy YellowToken |
DeployFaucet.s.sol |
deploy-faucet.sh |
Deploy Faucet (testnet only) |
DeployTreasury.s.sol |
— | Deploy Treasury |
DeployRegistry.s.sol |
— | Deploy registries + parameter administration |
cp .env.example .env
# Fill in values, then run the scriptsSee .env.example for all available variables.
./script/deploy-token.sh
./script/deploy-faucet.shSet NETWORK="mainnet" in .env, then:
./script/deploy-token.shAfter deploying, rebuild the SDK and docs to pick up new addresses from broadcast artifacts:
make sdk-build # extracts ABIs + addresses
make docs # regenerates docs (including address tables)make release v=1.1.0
git push origin master --tags
cd sdk && npm publishMIT (contracts) / GPL-3.0-or-later (YellowToken)