-
-
Rilva: climate evidence, verifiable relief (testnet demo)
-
Climate explorer: OND 2021 at Yabelo was 33.63 % of the 1991–2020 normal (ERA5)
-
Campaign #1: released to the fixed beneficiary after a signed attestation
-
Architecture: rule, evidence, attestation, contract, public verification
-
Public verification: 7/7 checks pass with no wallet
-
Campaign #2: OND 2023 at 213.22 % of normal, refunded to the funder (rule not met)
Track: Climate Data & Environmental Monitoring. Rilva tackles a problem this track names directly: environmental data is fragmented and hard to verify. We turn a rainfall-based funding rule into evidence that anyone can recompute, and a payment that only a public rule can trigger.
Testnet demonstration with historical data. No real funds, no insurance, no relief delivered. The 60 % threshold is illustrative.
Inspiration
Anticipatory climate finance often runs on a simple promise: if the rains fail, release the funds. In late 2021 the October–December rains failed across southern Ethiopia. FEWS NET reported rainfall at 45–75 % of average in the southern pastoral areas, including Borena.
When a decision like that is made, an outsider can rarely answer three questions. Which data was used? How was the number computed? Who decided, and did the money go where it was promised? Often the answer sits in a spreadsheet and an email thread. We wanted to see how far a small, honest system could go in making that chain checkable by anyone, without asking them to trust us.
What it does
Rilva is a working demo of one rule, studied in depth at one place: seasonal rainfall at Yabelo, Borena (Ethiopia), compared with the 1991–2020 normal. The same rule is also replayed at three more places to show the method is not tied to one site.
- A public rule, fixed before money moves. A funder chooses a season. The spec (location, data source and model, season, baseline, threshold) is hashed and stored in a smart contract together with the locked test ETH, the beneficiary and the attestor.
- Reproducible evidence. SRPN-v1 (seasonal rainfall percent of normal) is computed from ERA5 reanalysis via Open-Meteo, using integers only. OND 2021 comes out at 33.63 % of normal, OND 2022 at 44.61 %, and OND 2023 at 213.22 %. The inputs and result are canonicalised (RFC 8785) and hashed into a single evidence digest.
- A named attestor signs exactly what they checked. The attestor recomputes the evidence in their browser, reviews a readable EIP-712 message, and signs it in their own wallet.
- The contract applies the rule itself.
RilvaEscrowchecks the signer, spec, period and expiry, compares the index with the threshold, and either releases the funds to the fixed beneficiary once or refunds the funder. If nobody settles, anyone can refund after the deadline. - Anyone can verify, with no wallet.
/verify/[id]reads the chain and decodes the signed attestation. It recovers the signer, re-downloads the SHA-256-pinned ERA5 files, and recomputes the index and the hash. Seven checks each say what they prove, and the page says what it cannot prove.
Real on-chain runs (Base Sepolia):
- Campaign #1: OND 2021, 3363 bps ≤ 6000, Released (tx).
- Campaign #2: OND 2023, 21322 bps, Refunded, rule not met (tx).
- Campaign #3: OND 2022, active. Try to break it: forged signatures and early refunds are rejected by the deployed contract (simulated with
eth_call, nothing sent).
Same rule, other places (each in its own ERA5 cell and local timezone; settled on Base Sepolia, 7/7 checks with no wallet):
- Campaign #4: Marsabit, Kenya, OND 2021: 27.88 % of the 1991–2020 normal, Released.
- Campaign #5: Petrolina, Brazil, MAM 2012: 4.81 % of the 1981–2010 normal, Released.
- Campaign #6: Beed, India, JJAS 2015: 85.86 % of the 1981–2010 normal, Refunded, rule not met. IMD reported a 50 % monsoon deficit for Beed that year; this ERA5 cell does not show it, and Rilva shows the disagreement instead of adjusting the number.
Brazil and India use the 1981–2010 normal because those seasons fall inside 1991–2020; the baseline is part of the hashed rule.
How we built it
- Climate engine (TypeScript): strict validation of untrusted Open-Meteo JSON (
models=era5,daily=precipitation_sum,timezone=Africa/Addis_Ababa). Any missing day, null or error makes the resultINVALID; we never gap-fill. Rainfall is normalised to tenths of a millimetre and the index uses BigInt (floor(T × 10000 × N / S)). Our own RFC 8785 JCS implementation feeds keccak256 evidence digests. - Evidence: raw API responses are committed byte-for-byte with SHA-256 hashes in a manifest. Golden tests pin 3363 / 4461 / 21322 bps (and a 5468 bps reference case).
- Smart contract: Solidity 0.8.37 with OpenZeppelin
EIP712,ECDSAandReentrancyGuard. It is ownerless and non-upgradeable, makes no arbitrary calls, and follows checks-effects-interactions. It was built test-first with Hardhat 3: 79 tests covering every revert path with its exact custom error, a randomised invariant test, cross-language EIP-712 digest parity (viem vs Solidity), and real-evidence journeys. Line coverage ofRilvaEscrow.solis 100 %. - App: Next.js 16, React 19, Tailwind CSS 4, viem and wagmi, TanStack Query and Recharts. There is no backend database: campaign history is read straight from the contract. Deployed on Vercel. 242 Vitest tests, plus Playwright journeys and a forbidden-claims copy audit that runs as a test.
Challenges we ran into
- Choosing a dataset that doesn't change under you. Open-Meteo's default
best_matchswitches models in 2017, which makes a 1991–2020 baseline meaningless, so we pinmodels=era5. ERA5 and CHIRPS also disagree: CHIRPS puts OND 2021 at 52.5 %, and in MAM 2021 one dataset meets the rule while the other doesn't. Rather than hide it, the explorer shows the disagreement, and the data source is part of the hashed rule. - Then the data changed anyway. Two days before submission, our live check reported that Open-Meteo had revised its ERA5 archive in place. Hundreds of daily values had shifted slightly, and OND 2021 had moved from 3363 to 3362 bps. Every decision was the same, but a "re-fetch and compare" design would have turned every past attestation red. We now pin verification to the hashed snapshot files and show the live value next to it as an "upstream revised" note. That incident is now a core part of how we think about oracle honesty.
- Integer math that matches Solidity. No floats in the decision path. Equality triggers (
≤), and floor rounding is documented and tested on both sides. - Real wallets are messier than test wallets. Our testnet wallet submitted transactions through a smart-account relayer, so the
settle()call was nested inside another call and the verify page couldn't decode it. We now find the nested call, while the signer and field checks stay as strict as before. - Public RPC limits. Base Sepolia's public endpoint caps log queries at 200 blocks, so history is located by binary search over contract state instead of scanning.
Accomplishments that we're proud of
- A full lifecycle on a public testnet: create → attest → release, and create → attest → refund, all verifiable by a stranger with 7/7 checks passing.
- Climate numbers anyone can reproduce byte for byte, with the honest caveats attached.
- Security tests for every way we could think of to move the funds wrongly: a stranger's signature, an altered index, a swapped evidence hash, replay, settling twice, early refund, and reentrancy.
- A product that says what it does not prove, on the same page as the green checks.
What we learned
- A matching hash proves integrity and reproducibility, not truth. ERA5 is a ~28 km model estimate, not a rain gauge, and rainfall deficit is not drought impact or financial loss.
- The attestor stays a trusted party. Cryptography doesn't remove that trust, but it makes every claim checkable and every lie attributable.
- Live climate APIs are not immutable records. Reproducibility needs content-addressed inputs plus a deterministic method.
What's next
These are possibilities, not features we have built:
- Multiple attestors (k-of-n), so no single data steward decides alone.
- Independent data-source validation, such as CHIRPS and station data as co-signed cross-checks, and published snapshot archives (for example on IPFS).
- More places and seasons, and indicators such as SPI, calibrated with the programmes and communities they would serve.
- Field verification and partnerships with anticipatory-action and adaptation-finance practitioners, then a controlled, audited pilot.
Practical use and scalability
The pattern suits any programme that already pre-agrees a climate trigger: anticipatory-action funds, adaptation grants, or NGO cash programmes. Rilva doesn't replace their judgement. It gives their rule, their data and their decision a public, checkable record. Running costs are small: a few hundred thousand gas per campaign on an L2, and static hosting for evidence. Verification costs nothing to the person checking. Before any real money, it would need methodology validation with domain experts, multi-attestor governance, a professional contract audit and legal review. None of these exist today.
Built With
- base-sepolia
- eip-712
- era5
- ethereum
- hardhat
- keccak256
- next.js
- open-meteo
- openzeppelin
- playwright
- react
- recharts
- rfc-8785
- solidity
- tailwindcss
- tanstack-query
- typescript
- vercel
- viem
- vitest
- wagmi
Log in or sign up for Devpost to join the conversation.