FA591 Blockchain & DeFi · Stevens Institute of Technology · Spring 2026

CongressChain

I built CongressChain to make congressional trade records and their scores easier to check. The prototype records a small set of disclosures on Base Sepolia. Each record includes a score calculated by a public smart contract, so a reader can check the inputs and repeat the calculation.

Try the score

same formula as SuspicionScorer.sol
0/ 100
0Delay0Committee0Hearing0Amount
Author
Zhenhan Chen
Stack
Solidity 0.8.24 · OpenZeppelin v5 · Foundry · ethers v6
Network
Base Sepolia testnet (chain 84532)
Data
Public STOCK Act filings · demo set of 5 members and 15 trades on chain
01

Public records and verifiable scores

Readers should be able to check both a record and the calculation applied to it.

The project starts with congressional trade disclosures and asks how to preserve a record of the data used for scoring. It brings the trade, scoring inputs and result into a public ledger. This makes the calculation inspectable without relying on the website's display alone.

TradeRecord stores entries without an edit or delete operation and calculates each score when the entry is added. The current prototype still relies on its owner to submit records and set the weights. Public computation does not verify that the original filing was parsed correctly.

FilingsHouse Clerk and Senate eFD disclosures, normalized to JSON
RegistryMembers, chamber, party and committee seats
Ledger + scoreTradeRecord stores the trade and asks SuspicionScorer for its score
FrontendRankings, trade list and a score audit read straight from the chain
02

The score

Four sub-scores from 0 to 100, weighted in basis points that sum to 10,000.

FactorWeight0 when100 when
Disclosure delay15%filed same day≥ 90 days (45-day limit = 50)
Committee jurisdiction30%no related committeesits on a related committee
Proximity to a hearing35%≥ 30 days away≤ 3 days away
Trade size20%< $15,000≥ $1,000,000
function score(uint32 delayDays, uint8 committeeRelevant, uint256 amountUsd, uint32 daysToHearing)
    external view returns (uint8)
{
    uint256 total = ( _delaySubscore(delayDays)       * weights.delay
                    + (committeeRelevant > 0 ? 100 : 0) * weights.committee
                    + _hearingSubscore(daysToHearing)  * weights.hearing
                    + _amountSubscore(amountUsd)       * weights.amount ) / 10_000;
    return uint8(total > 100 ? 100 : total);
}

Weights are owner-settable in this version, with every change emitted as an event; the design hands them to holders of the project's SUN token in a later version. Integer arithmetic means the calculator above matches the contract exactly.

03

Contracts

Five Solidity contracts. The course submission includes 18 Foundry tests.

ContractRoleAddress (Base Sepolia)
04

Live demo

The original course frontend, reading the deployed contracts through a public RPC. No wallet needed to browse.

This is a testnet prototype with 5 members and 15 trades. Where a filing date was missing, the demo uses trade date + 30 days. The score illustrates the formula; it is not evidence of misconduct. The presentation also proposes token-funded data submissions and community voting on weights. Those are future plans, not features of this demo.