Smart contract plugins for Orion Finance: onchain strategists, deposit access controllers, and external depositor helpers.
Each plugin implements a protocol-defined interface from @orion-finance/protocol.
If you have an idea for a strategist, access policy, or depositor flow, this is the place to build it, test it against the real protocol stack, and share it with others.
Requires Node.js ≥ 24 and pnpm.
pnpm install
pnpm build
pnpm test
pnpm lint
pnpm coverageFor protocol architecture and interface docs, see docs.orionfinance.ai.
One Hardhat script deploys a single plugin. KBest operation (cron / submitIntent) stays in IOrionStrategist-template; this CLI is how you get an address. manager-only and non-transferable are safe to reuse across vaults; whitelist is per-manager.
PLUGIN |
Contract | Extra env | What it does |
|---|---|---|---|
whitelist |
WhitelistAccessControl |
OWNER (default: deployer) |
Allowlist for deposit / holder / transfer |
manager-only |
ManagerOnlyDepositAccessControl |
— | Only the vault manager may deposit |
non-transferable |
NonTransferableSharesAccessControl |
— | Blocks P2P share transfers; redeem still works |
tvl-cap |
TvlCapDepositAccessControl |
TVL_CAP |
Caps projected vault TVL |
max-ticket |
MaxTicketSizeDepositAccessControl |
MAX_TICKET_SIZE |
Caps per-depositor cumulative deposit (pending + settled + this request) |
nft |
NftOwnerAccessControl |
CREDENTIAL |
Requires an ERC-721 credential |
blacklist |
BlacklistRejectAccessControl |
DENYLIST |
Rejects addresses on a denylist |
signed-ticket |
SignedTicketAccessControl |
ATTESTER, EIP712_NAME, EIP712_VERSION |
Off-chain signed tickets |
ens |
EnsSubtreeAccessControl |
ENS_REGISTRY, ROOT_NODE |
Wallet must resolve under an ENS root |
eas |
EasAccessControl |
OWNER, EAS, SCHEMA_UID, TRUSTED_ATTESTERS, POLICY_MODE (0 email / 1 nationality), EMAIL_DOMAIN_HASH, COUNTRY_CODES |
EAS attestation gate |
all-of |
AllOfDepositAccessControl |
GATES (comma addresses) |
AND-composes deposit gates |
trex |
TrexAccessControl |
IDENTITY_REGISTRY, optional MODULAR_COMPLIANCE |
ERC-3643 Identity Registry (+ optional ModularCompliance) bridge; ONCHAINID-backed isVerified; compliance uses vault-passed (from, to, value) |
router |
OrionDistributionRouter |
SEPOLIA_ORION_CONFIG_ADDRESS / MAINNET_ORION_CONFIG_ADDRESS |
Distributor-routed requestDepositFor |
tvl |
KBestTvlWeightedAverage |
SEPOLIA_ORION_CONFIG_ADDRESS / MAINNET_ORION_CONFIG_ADDRESS, STRATEGIST_K (default 10), optional VAULT_ADDRESS (vault manager calls updateStrategist) |
Top-K by TVL, TVL weights |
apy-equal |
KBestApyStrategist |
same | Top-K by APY, equal weights |
apy-weighted |
KBestApyStrategist |
same | Top-K by APY, APY weights |
cp .env.example .env
PLUGIN=whitelist OWNER=0x... pnpm deploy:sepolia
PLUGIN=whitelist OWNER=0x... pnpm deploy:mainnet
PLUGIN=manager-only pnpm deploy:sepolia
PLUGIN=router pnpm deploy:sepoliaRequired in .env: PRIVATE_KEY, plus SEPOLIA_RPC_URL and/or MAINNET_RPC_URL for the target network (no bare RPC_URL). PLUGIN is set on the command. Writes deployments/<network>-<timestamp>.json.
On non-local networks, if ETHERSCAN_API_KEY is set the script verifies the contract after deploy. Set SKIP_VERIFY=1 to skip. Without an API key it prints a manual npx hardhat verify command instead.
SEPOLIA_ORION_CONFIG_ADDRESS / MAINNET_ORION_CONFIG_ADDRESS are used by router, tvl, apy-equal, and apy-weighted only. Other plugins do not read them. --network mainnet requires MAINNET_ORION_CONFIG_ADDRESS; sepolia / hardhat / localhost require SEPOLIA_ORION_CONFIG_ADDRESS. No default, no ORION_CONFIG_ADDRESS.
- Implement the relevant interface from
@orion-finance/protocol. - Add unit tests with mocks where possible.
- Add integration tests using
deployUpgradeableProtocol()fromtest/helpers/deployUpgradeable.ts. - Never import protocol implementation contracts in production plugin Solidity.
We welcome contributions of all kinds! Bug reports, new plugins, tests, docs. See CONTRIBUTING.md to get started.