Skip to content

Platform Contracts

umermjd11 edited this page Oct 5, 2026 · 4 revisions

Platform Contracts

🚧 This wiki describes DevNet 2.0, soon to be launched. It follows the contracts and dincli on the develop branch; the currently running DevNet may still use older contracts and commands. Pre-launch discussion: #102.

The platform contracts are the foundation of the DIN Protocol. They are seven Solidity contracts, deployed once per network by the DIN-Representative, and every model, validator and client on the network builds on them. The live DevNet runs on Optimism Sepolia (chainId 11155420).

They are distinct from the Task Contracts, which each model owner deploys per model.

Each platform contract sits behind an OpenZeppelin Transparent Proxy with its own ProxyAdmin, so it can be upgraded without changing its address. The deployer, normally the DIN-Representative key, becomes the owner() of all seven contracts and all seven ProxyAdmins.

                    DIN-Representative (owner of all seven)

   ETH ──depositAndMint──► DinCoordinator ──mint──► DinToken
                             │    ▲    │
             authorizes      │    │    └──ETH sweep──┐
             slashers        │  mintEmission         ▼
                             ▼    │             DinFeeRouter ──treasury share──► DinTreasury
                  DinValidatorStake    DinEmission     ▲
                         ▲            (funds GI        │ ETH sweep
                 slash() │             reward pools)   │
                         │                       DINModelRegistry ◄── model owners
                Task contracts (per model)                             (requests + fees)

DinCoordinator

The protocol's entry point, minting gateway and slasher registry. It does not hold the treasury.

  • Buying DIN. Anyone can call depositAndMint() with ETH and receive newly minted DIN at the current rate, dinPerEth (default 1 ETH → 1,000,000 DIN). This is a one-way faucet: there is no redeem path back to ETH. The intent is for a DEX to take over price discovery later.
  • Emission gateway. mintEmission() is the only other way DIN is minted. Only the configured DinEmission contract can call it.
  • Supply guards. Both minting paths respect mintCap (0 means uncapped) and stop permanently once the owner calls retireFaucet(), which is one-way.
  • Fees. ETH received from DIN purchases stays in the coordinator until the DIN-Representative sweeps it to DinFeeRouter (sweepFeesToRouter, or dincli dinrep coordinator sweep-fees). There is no withdraw().
  • Slasher management. It is the only address allowed to add or remove slasher contracts on DinValidatorStake. This is how the DIN-Representative authorizes a model's task contracts to slash misbehaving validators.

Owner-only settings: updateDinPerEth, setMintCap, retireFaucet, setEmissionContract, setFeeRouter and updateValidatorStakeContract.

DinToken

The network's ERC-20 utility token: "DIN Token", symbol DIN, 18 decimals, no pre-mint.

  • Minting is restricted to DinCoordinator. The owner binds the coordinator once, with setCoordinator, during deployment.
  • Burning: any holder can burn() their own tokens. The protocol burns DIN too, for example half of every slash.

DIN is the staking, slashing and reward currency. Validators buy it with ETH and lock it in DinValidatorStake. Models fund their per-GI reward pools in DIN.

DinValidatorStake

The staking ledger for validators (auditors and aggregators). It holds staked DIN, tracks each validator's lifecycle, and lets authorized slasher contracts penalize misbehaviour.

  • Minimum stake. Each stake() must be at least minStake (default 10 DIN, owner-settable). A validator can work only while Active. A model can also set a higher per-model stake floor.
  • Unbonding. Unstaking starts an unbonding period (default 7 days, owner-settable) before funds can be claimed. Pending withdrawals remain slashable until claimed, so a validator can't dodge a penalty by exiting.
  • Slashing. Only registered slasher contracts (a model's DINTaskCoordinator and DINTaskAuditor) can slash. Of every slash, 50% is burned and 50% goes to the slash treasury.
  • Repeat offences (S5). Liveness faults (missed votes or submissions) are partial slashes. A validator who repeats them within the S5 window gets a full minStake slash and is jailed (default 7 days), after which it can reactivate.
  • Blacklisting. The owner can blacklist a validator address, which blocks staking, exits and withdrawal claims.
  • Encryption keys. Auditors register an X25519 public key here (registerEncryptionKey), so model owners can send them encrypted test data.

Validator status moves through None → Active → Exiting, plus Jailed and Blacklisted. If active stake falls below the minimum, the validator stops being Active.

DINModelRegistry

The governed admission gateway for models. Every model on the network is registered here and gets a unique ID. Admission works by request and approval:

  • Two-phase registration. The model owner submits a registration request. The DIN-Representative reviews it and approves or rejects it. Only approved models receive an ID.

  • Two-phase manifest updates. Changing a model's manifest CID, which can change its training logic and parameters, follows the same request and approval flow.

  • Prerequisite. The model's DINTaskCoordinator and DINTaskAuditor must already be slashers on DinValidatorStake. Approval checks this again at execution time.

  • Two model types.

    • Open-source models: anyone may use the trained model freely.
    • Proprietary models: the trained model belongs to the owner and can be used commercially. Their fees are higher.
  • Fees. Small ETH fees are charged per request and kept whether the request is approved or rejected. The DIN-Representative sets them and sweeps the collected ETH to DinFeeRouter:

    Fee Open-source Proprietary
    Registration 0.000001 ETH 0.00001 ETH
    Manifest update 0.0000001 ETH 0.000001 ETH
  • Disable / enable. The DIN-Representative can disable a model. This blocks new manifest update requests and approvals for it. The task contracts don't read this flag, so a disabled model's running GIs, submissions and slashing continue.

DinFeeRouter

Splits protocol fees across four buckets: validator pool, treasury, storage and public goods. DIN fees can also have a burn share.

  • Only allowlisted fee sources can route fees. The deploy script allowlists DinCoordinator and DINModelRegistry.
  • The default ETH split is 95% validator pool / 5% treasury. The treasury share can't exceed a 20% ceiling.
  • Only the treasury share leaves the router today. The validator-pool, storage and public-goods shares accrue in the router until the contracts that will consume them ship.

DinTreasury

A custodial holding contract for ETH and ERC-20 assets, with no split logic of its own. It receives the router's treasury share. The owner can withdraw from it with withdrawETH and withdrawERC20.

DinEmission

The per-GI reward subsidy. It funds a model's GI reward pool on a geometric decay schedule:

  • Each epoch (a fixed number of completed GIs) keeps a set fraction of the previous epoch's emission.
  • After maxEpochs, emission stops. This is an explicit retirement, not an endless tail.
  • Progress is tracked per model, because every model has its own GI counter.

It mints only through DinCoordinator.mintEmission(), so emission can't bypass mintCap or faucet retirement.

Deployment

The Foundry script foundry/script/DeployPlatform.s.sol deploys and wires all seven contracts in one run: 22 transactions (seven implementations, seven proxies and eight wiring calls).

1. DinTreasury proxy
2. DinToken proxy
3. DinFeeRouter proxy (token, treasury)
4. DinCoordinator proxy (token)
      → DinToken.setCoordinator · DinCoordinator.setFeeRouter · DinFeeRouter.addFeeSource(coordinator)
5. DinValidatorStake proxy (token, coordinator)
      → DinCoordinator.updateValidatorStakeContract · DinValidatorStake.setSlashTreasury(treasury)
6. DINModelRegistry proxy (stake)
      → DinFeeRouter.addFeeSource(registry) · DINModelRegistry.setFeeRouter
7. DinEmission proxy
      → DinCoordinator.setEmissionContract
8. Tokenomics overrides from the environment (DIN_PER_ETH, MINT_CAP, EMISSION_*, MIN_STAKE, S5_*, …)
9. Write foundry/deployments/<network>.json, then: dincli system import-deployments

Later, for each model: the DIN-Representative runs dincli dinrep add-slasher for its coordinator and auditor, the model owner requests registration, and the DIN-Representative approves it.

Ownership. Each contract changes owner with OpenZeppelin transferOwnership, and each ProxyAdmin has its own owner. There is no single set-admin switch. Upgrades go through foundry/script/UpgradePlatform.s.sol.

Further reading

Introduction

DIN Components

Network Roles

Clone this wiki locally