Animal-backed lending/borrowing with ERC-1155 collateral, deployed via usecannon + Foundry. This doc explains how to build, why the Cannonfile looks the way it does, and the gotchas we hit (and solved) around oracles, dependency resolution, and schema quirks.
-
forge build && cannon build deploys:
-
MockUSDC (test stablecoin)
-
SpeciesToken (ERC-1155 animals)
-
SpeciesOracle (simple price oracle)
-
SpeciesLending (lending core)
-
-
Seeds USDC + species balances, configures risk, and posts three price observations per species so the oracle’s median is valid.
-
Accepts price for species id=1 only. (Ids 2 & 3 skip accept() due to the contract’s first-accept math edge-case; details below.)
--
-
Solidity/Foundry for contracts & artifacts.
-
usecannon for deterministic deployments & post-deploy calls.
-
Local Anvil chain spawned by Cannon during build.
--
We intentionally use artifact = "src/File.sol:Contract" to match Cannon’s legacy schema.
/src
MockUSDC.sol
SpeciesToken.sol
SpeciesOracle.sol
SpeciesLending.sol
cannonfile.toml--
- Migrate admin to a multisig.
- Remove all dev_* invokes.
- Verify contracts and publish sources.
- Add pause/guardian tests & runbooks.
- Add price-feed diversity (not just 1 reporter).
- Simulate stress events (oracle outage, price gaps, collateral cascades).
Financially it’s a lending market that mints/borrows stable liquidity (USDC) against tokenized livestock. You deposit cow-tokens, get credit, repay, or get liquidated if price drops below risk thresholds.
It’s basically Fungible Collateral → Borrow Fiat.
Technical risks: — Oracle assumptions: 3 price posts needed to form a median. If the reporter feeds garbage or is censored, risk parameters break. — Smart contract logic: underflow/overflow edge cases on first “accept” baseline. — Liquidations require precise price freshness or the bad actor can mint → borrow → dump within a stale heartbeat.