Seed Protocol
Contracts

Deployments

Live Seed Protocol contract addresses on OP Sepolia, how each was checked on-chain, who holds the factory roles, when the current contracts went live, and older addresses that are no longer used.

Seed Protocol's contracts are deployed on OP Sepolia (chain ID 11155420), an Optimism testnet. They're built with solc 0.8.38, EVM target cancun. There's no mainnet deployment yet (Roadmap). With this bytecode, deployer and salt, SeedProtocolExecutor would land at the same address on mainnet; the extensions take the EAS address as a constructor argument, so theirs would differ. The contracts repo's Ignition record (ignition/deployments/chain-11155420/) is the source of truth for these addresses.

OP Sepolia

ContractAddressExplorer
SeedProtocolExtension0x851C5527240CAD1f6839B1379c5A348b59B14437Etherscan
SeedProtocolExecutor0xa4799d6D6AF110D5d69437488aBC31A5ef8ACA5fEtherscan
SeedExecutorRouterExtension0xBC32e3e404C339AbDd66A9840c825BF5c287c533Etherscan
thirdweb ManagedAccountFactory0x76F47D88bfaf670F5208911181fCDC0E160cb16dEtherscan
EAS (OP Stack predeploy)0x4200000000000000000000000000000000000021Etherscan, easscan
EAS SchemaRegistry (OP Stack predeploy)0x4200000000000000000000000000000000000020Etherscan
ERC-4337 EntryPoint v0.6 (used by the factory's accounts)0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789Etherscan

The three Seed contracts were deployed with CREATE2 through CreateX, with a salt only Seed's deployer can use. The contracts repo's deploy log records source verification on Etherscan and Sourcify; the checks below don't cover that. The publish package has the factory and the EAS predeploys built in for OP Sepolia; you set the executor yourself with modularAccountModuleContract (see Publish overview). You never send anything to the extension or router extension addresses directly: your account runs their code.

How these were checked

Every row above has contract code on OP Sepolia (eth_getCode). These read-only calls, made on 2026-10-30 against https://sepolia.optimism.io (block 50,799,058), show the configuration:

CallResultWhat it shows
SeedProtocolExtension.getEas()0x4200…0021The extension is pinned to the EAS predeploy
SeedExecutorRouterExtension.getSeedExecutor()(0xa479…CA5f, 0x4200…0021)The router extension trusts this executor and EAS
SeedProtocolExecutor.isModuleType(2)trueIt's an ERC-7579 executor module
factory.getImplementationForFunction(0xa1263421) (multiPublish)0x851C…4437Accounts route multiPublish to the current extension
factory.getImplementationForFunction(0xd5f5127d) (getEas)0x851C…4437Same for getEas
factory.getImplementationForFunction(…) for installSeedExecutor, uninstallSeedExecutor, isModuleInstalled, getSeedExecutor, executeFromExecutor0xBC32…c533Accounts route the executor functions to the router extension
factory.getImplementationForFunction(0xb90b6e0d) (setEas), (0x31e19cb8) (the old string-localId multiPublish) and (0x2a29fadc) (the multiPublish without list elements)0x0000…0000Retired functions are no longer routed, so a client built for 0x2a29fadc gets a Router revert
factory.entrypoint()0x5FF1…2789Accounts use EntryPoint v0.6
factory.hasRole(role, 0x00467fe2608Dff148C83009927E4e7234Bc4D84B) and getRoleMemberCount(role) for keccak256("EXTENSION_ROLE") and DEFAULT_ADMIN_ROLEtrue, 1 for eachA single Seed-operated key, Seed's deployer, holds both factory admin roles: the one that changes routing and the one that grants roles
EAS.getSchemaRegistry()0x4200…0020EAS and the SchemaRegistry belong together
SchemaRegistry.getSchema(uid) for the three base schemasregistered, no resolver, revocableThe schemas every publish needs are in place

You can repeat any of them with cast call (Foundry) or any JSON-RPC client. For example:

cast call 0x76F47D88bfaf670F5208911181fCDC0E160cb16d \
  "getImplementationForFunction(bytes4)(address)" 0xa1263421 \
  --rpc-url https://sepolia.optimism.io
# 0x851C5527240CAD1f6839B1379c5A348b59B14437

At runtime, the publish package's verifyPublishChain() checks that the RPC serves the configured chain and that the EAS, SchemaRegistry, factory and executor addresses have code, readFactorySeedExecutor() reads which executor and EAS the factory's router extension trusts, and assertMultiPublishRouted(target, { executorModule }), which a contract publish runs first, fails with MULTI_PUBLISH_NOT_ROUTED when the target doesn't have the multiPublish the package sends (MULTI_PUBLISH_SELECTOR).

History

The current contracts went live on 2026-10-30, when the factory's routing switched to them in one multicall (block 50,793,041, 0xbcc3a306…6617). They add the three-phase multiPublish (selector 0xa1263421), references to list elements and an exact msg.value check, and the install record now stores the executor's address. @seedprotocol/publish 0.8.0 is built for them. Releases from 0.6.9 to 0.7.13 send 0x2a29fadc, which isn't routed any more, so they can't publish through a ManagedAccount; direct EAS, reads and item.unpublish() still work. Each account's admin installs the new executor, and session keys are granted again (After the factory moves to a new executor).

The set before that went live on 2026-10-03, in one transaction (block 49,632,889, 0xce3b77ed…e314). It replaced an extension whose multiPublish had no caller check and which exposed setEas, and it added the router extension. @seedprotocol/publish releases before 0.6.9 were built for the earlier contracts. As of 2026-10-18, three accounts had installed that set's executor (the first on 2026-10-04) and none had uninstalled it. The number of accounts still on it today hasn't been read.

What's left of the rollout is in Seed's own apps and test accounts; see Roadmap.

Not in use

These addresses on OP Sepolia hold Seed code but aren't routed by the factory. Don't install, route or point an app at any of them. The implementations from before 2026-10-03 have known access-control bugs.

AddressWhat
0xde5F3133D9A4a4957ad44b4C8d44D0cfaf0A4A6B, 0x80562aeEe4F16473779b1474D8D32d114D302e94, 0xeE9CA71f3a91fC2832cc031318F0Bc4B3908D30aThe 2026-10-03 extension, executor and router extension, routed until 2026-10-30. Accounts did install this executor, so an account can still carry its configuration. The executor has only the 0x2a29fadc multiPublish, and the router extension recorded the install as a flag, which vouched for a replacement executor.
0xe8A567d96BaaF98805A186bb825cC0b2430b607AThe SeedProtocolExtension implementation routed until 2026-10-03. Its multiPublish had no caller check, and it had a public setEas.
0x043462304114da543add6B693c686B7d98865F3EAn earlier SeedProtocolExecutor, from before its value-handling fix. No account ever installed it.
0x2ee2571cF7C68998292A6E1715Dc4F799A4D5CB4, 0xF24554E658F167d5DE937066be4824C731183880, 0x7AaC33b02a63035452fA5eee07F45351c0684B62, 0x8eAe1425c19394b1199eA553f50547A6bA8FEf08A deployment made earlier on 2026-10-03 and superseded the same day before routing switched (extension, extension V2, executor, router extension)
0xA2b8315fd0F31c334be1B137D9E0FfbB3F200E57, 0x0F47BcE73b6132d6CE45903400EED6702594b666, 0x9508D87306c443B6965db831417FE76ec4c4b596, 0xf331b31A8e613320AA4b78ee908ee639E5936da8OpenZeppelin proxies from the original, proxy-based design

@seedprotocol/publish also exports MULTI_PUBLISH_ABI_REFERENCE_ADDRESS_OP_SEPOLIA, 0xcd8c945872df8e664e55cf8885c85ea3ea8f2148, marked internal, with a comment that says not to send transactions to it. It isn't part of the deployment above, and it's a 45-byte clone whose code has no 0xa1263421, so the multiPublish the package sends isn't there.

Other chains

OP Sepolia is the only network with a deployment. Addresses on another chain would differ for the extension and the router extension, because the EAS address is a constructor argument and EAS isn't at the same address everywhere. Deploying to a new chain walks through the process, and Local twin covers the local fork of OP Sepolia, which runs under chain ID 31337.

On this page