4.9 KiB
AGENTS.md
Guidance for AI agents working on this repository.
Project overview
@kredits/contracts — Solidity smart contracts and a JavaScript (ethers v5)
wrapper for Kosmos Kredits, a contribution
tracking DAO running on EVM chains (primarily RSK). Contributors earn kredits
for contributions; kredits are withdrawable as ERC20 tokens. All contracts are
upgradeable via OpenZeppelin hardhat-upgrades proxies.
Tech stack
- Solidity ^0.8.0 (compiler 0.8.2), OpenZeppelin upgradeable contracts
- Hardhat (with @openzeppelin/hardhat-upgrades, hardhat-deploy, hardhat-waffle)
- JavaScript (CommonJS), ethers v5, ipfs-http-client
- Tests: mocha + chai + @nomicfoundation/hardhat-chai-matchers
- Lint: solhint (contracts), eslint (JS)
Repository layout
contracts/— Solidity smart contracts (see "Contracts" below)lib/— published JavaScript API wrapper (entry:lib/kredits.js)lib/contracts/— one wrapper class per contract, extendingBase/Recordlib/serializers/— IPFS JSON serializers (contributor, contribution)lib/utils/— ipfs, pagination, validator, preflight, deprecate, format-kreditslib/abis/— committed ABI JSON (regenerated bynpm run build:json)lib/addresses.json— chainId → deployed contract addresses
scripts/— hardhat CLI helpers (create-proxy, seeds, add-/list-*, build-json, upgrade-example, import/, export/)test/contracts/— mocha tests (Contributor.js, Contribution.js)config/seeds.js— demo seed datahardhat.config.js— networks: hardhat (1337), rinkeby, rsk (RSK testnet); injectshre.kredits(an initializedKreditsinstance)
Contracts
All in contracts/, all Initializable (OpenZeppelin upgradeable):
Contributor.sol— contributor registry (account + IPFS profile hash). Core team = contributor IDs 1–6 (hardcoded).withdraw()mints tokens for confirmed, not-yet-withdrawn kredits.Contribution.sol— contribution records (ERC721-like ownership). Veto period ~40320 blocks (~7 days @ 15s blocks).add()→ veto window → confirmed.Reimbursement.sol— expense reimbursements, same veto pattern.Token.sol— ERC20 "Kredits" (symbol KS, 0 decimals).mintForcallable only by the Contributor contract.
Contracts are independent and reference each other by address (set via
setContributorContract, setContributionContract, setTokenContract).
Wiring happens in scripts/create-proxy.js.
Common commands
Bootstrap a local dev environment:
npm install
npm run devchain # hardhat node --network hardhat (separate terminal)
npm run bootstrap # build + deploy proxies + seeds (uses localhost)
Other:
npm run build # compile contracts + regenerate lib/abis
npm run deploy:dao # deploy upgradeable proxies (scripts/create-proxy.js)
npm run seeds # seed demo data
npm run fund # send devchain ETH to an address
npm test # hardhat test (requires devchain running)
npm run lint:contracts # solhint
npm run lint:wrapper # eslint lib/
Run a hardhat script: hardhat run scripts/<name>.js --network localhost
(or --network rsk for RSK testnet). Use DEPLOY_KEY=<hex> to override the
deploy account.
Conventions
JavaScript (eslint: lib/, scripts/, test/)
- CommonJS (
require/module.exports) - 2-space indentation; semicolons required
- Trailing commas in multiline arrays/objects (not in imports/exports)
- Space before named function parens:
function foo () {},async () => {} - Async wrappers use
.then()chains in older code; new code may use async/await
Solidity (solhint: default + recommended)
pragma solidity ^0.8.0;- Upgradeable pattern:
import Initializable, useinitialize()(andreinitializer(n)for upgrades) — never use constructors for state init - Interfaces declared inline (e.g.
ContributorInterface) for cross-contract calls - Core-only / deployer-only / contributors-only modifiers guard privileged calls
Upgradeable contract changes
- Do not use constructors to initialize state (use
initialize/reinitializer) - Do not change the order/types of existing storage variables (storage layout!)
- New storage vars go at the end of the contract
- See
scripts/upgrade-example.jsandscripts/create-proxy.js
Tests
Mocha + hardhat-waffle + chai-matchers. test/contracts/ only covers
Contributor and Contribution today. When changing contract code, add/adapt
tests there. Requires a running devchain (npm run devchain) for npm test.
Networks & deployment
hardhat(chainId 1337) — local devchainrsk(RSK testnet, https://rsk-testnet.kosmos.org) — primary test deploymentrinkeby— legacy, configured but deprecated- Deployed addresses are tracked per chainId in
lib/addresses.jsonand must be committed when deployment changes (seenpm run versionscript)