THE PLIMSOLL LOAD LINE FOR AGENTS
An autonomous agent wants credit. It wants to borrow capital, trade on margin, take delivery of GPU compute before payment, or be entrusted with an institutional mandate. The counterparty agent needs to verify solvency before taking on counterparty risk.
Today's Two Flawed Options:
- Publish your full balance sheet: Now the counterparty knows your exact liquid reserves, margins, and exactly how hard to squeeze you in negotiations.
- Rely on blind reputation / word: Worthless in decentralized, pseudonymous agent-to-agent commerce.
The Historical Analogy
In the 1870s, British MP Samuel Plimsoll established the Plimsoll Line—a reference mark painted on a ship's hull. When a cargo vessel docks, the harbourmaster checks whether the water level is below the mark. The harbourmaster never opens the cargo hold, never reads the manifest, and never calculates the exact tonnage.
One bit of information is enough to decide safely. Plimsoll does the same for autonomous agents: a counterparty pays a few cents to ask one question:
"Is this agent above the line?"
HARDWARE-ISOLATED NITRO ENCLAVES
Plimsoll evaluates balance sheets inside an AWS Nitro Enclave in region us-west-2 using Chainlink CRE (Compute Runtime Environment) and cre.handlerInTee.
- • CEX read-only API keys from Vault DON
- • Raw token balances and account holdings
- • Intermediate haircut evaluations
- • Enclave volatile execution memory
- • Triggers (EVM logs on Sepolia)
- • The 1-bit boolean verdict (`ABOVE`/`BELOW`)
- • Survey metadata: surveyId, asOf, sourceSetHash
- • No balance quantities ever cross the door
The One-Way Door: `runtime.usingTheDons()`
Whatever leaves the TEE handler passes through runtime.usingTheDons(). This payload is strictly audited:
// The crossing payload — the entire privacy claim
const donRuntime = runtime.usingTheDons();
const report = await donRuntime.report({
surveyId, // bytes32
subjectId, // bytes32 (ENS node / DID)
lineId, // uint16
verdict, // uint8: 0=INDETERMINATE, 1=ABOVE, 2=BELOW
asOf, // uint64 (Chainlink price timestamp)
sourceSetHash, // bytes32 (Haircut version + allowlist hash)
});Notice: No balance, no token amount, no margin ratio, no headroom.
HONEST METRICS & HAIRCUT SCHEDULE
Plimsoll does not call its metric net_equity_usd because off-balance-sheet debt cannot be observed by read-only API keys. Instead, the metric is explicitly defined as:
Published Haircut Table
| ASSET CLASS | HAIRCUT FACTOR | RATIONALE |
|---|---|---|
| USDC, USDT | 1.00 (100%) | Fiat-backed liquid stablecoins |
| ETH, WETH, BTC | 0.90 (90%) | Deep spot liquidity; 10% volatility cushion |
| All Other Allowlisted | 0.75 (75%) | Long-tail slippage & liquidation buffer |
ADVERSARIAL DEFENSES & LIMITS
1. Flash-Funding Defense: `Standing` Accumulator
A malicious borrower might take a flash loan for one block to pass a solvency check. Plimsoll solves this via Standing: the consumer contract (CreditDesk.sol) demands k distinct Mark executions spanning at least w seconds (e.g. 3 surveys over 1 hour). A single-block loan cannot produce a multi-hour run.
2. Binary-Search Leakage Defense: Pre-Registered Ladders
If an attacker could query any arbitrary threshold, they could binary search the agent's exact balance ($240k? no. $220k? yes...). Plimsoll forces counterparties to query only coarse rungs from the subject's pre-registered ladder, coupled with pair-scoped rate limiting per (subject, requester).
3. Credential Spoofing: EIP-712 Signature Binding
A subject cannot claim someone else's whale wallet. The subject must sign an EIP-712 binding proof with the wallet's private key, which is verified before the address is allowlisted for that subject ID.
COMPOSING CHAINLINK & PLIMSOLL ON BAZANTIC
Bazantic provides the MCP server and x402 payment gateway that turns Plimsoll into a composable tool for autonomous agents.
The Crucial Recipe Invariant
In the underwrite_counterparty Recipe, the agent is given an explicit instruction:
"On FALSE: Do NOT retry at a lower Line to discover the actual balance. Plimsoll rate-limits this per requester and the subject has not consented to it. Either require collateral, reduce exposure below an already cleared Line, or decline."
This rule defends the borrower's privacy against the agent's own natural curiosity.
SOLIDITY CONTRACTS ON SEPOLIA
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract PlimsollRegistry {
struct Mark {
bytes32 subjectId; // ENS node or agent DID (public)
uint16 lineId; // index into subject's ladder
uint8 verdict; // 0=INDETERMINATE, 1=ABOVE, 2=BELOW
uint64 asOf; // price timestamp
uint64 expiry; // block timestamp validity limit
bytes32 surveyId; // unique execution nonce
bytes32 sourceSetHash; // haircut schedule & source hash
}
address public immutable forwarder;
mapping(bytes32 => Mark) public marks;
event SurveyRequested(bytes32 indexed surveyId, bytes32 indexed subjectId, uint16 lineId);
event MarkPosted(bytes32 indexed surveyId, bytes32 indexed subjectId, uint8 verdict);
modifier onlyForwarder() {
require(msg.sender == forwarder, "not forwarder");
_;
}
function requestSurvey(bytes32 subjectId, uint16 lineId) external returns (bytes32 surveyId) {
surveyId = keccak256(abi.encodePacked(subjectId, lineId, block.timestamp, msg.sender));
emit SurveyRequested(surveyId, subjectId, lineId);
}
function postMark(bytes32 surveyId, Mark calldata mark) external onlyForwarder {
marks[surveyId] = mark;
emit MarkPosted(surveyId, mark.subjectId, mark.verdict);
}
}START TESTING IN 3 MINUTES
To test the protocol locally or connect an existing agent:
- Derive the Line: Call
/api/line-for/ETH/USD?amount=60&subjectId=0x...to price the exposure at a Chainlink feed and pick the lowest rung on the subject's ladder that covers it. - Simulate CRE workflow: Run
cre workflow simulatewith testnet credentials to verify that no balance amounts leak outside the AWS Nitro enclave simulator.