Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions fees/0xequity/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { FetchOptions, SimpleAdapter } from "../../adapters/types";
import { CHAIN } from "../../helpers/chains";

/*
* 0xEquity — rental income (Fees & Revenue) on Base.
*
* 0xEquity tokenizes real estate; each property's off-chain rental income is
* proven on-chain, trust-minimized, in the IncomeAttestationRegistry. A period
* (calendar month, periodId = YYYYMM) is "fully proven" only when two independent
* paths agree: a threshold-signed attestation (Path A) AND a Reclaim zkTLS proof
* of the same bank statement (Path B). On finalize the registry emits
* `FullyProven(token, periodId, totalMinor)` where totalMinor is the gross rental
* income for that property/month in USD minor units (cents).
*
* We treat that proven rental income as protocol Fees, and — since it accrues to
* the property-token holders (the suppliers of capital) — as supply-side revenue.
* The protocol's own management-fee cut is not yet counted here (see methodology).
*/

// IncomeAttestationRegistry (Base mainnet, source-verified). Holds every property's
// proven monthly rental income; emits FullyProven on finalize.
const REGISTRY = "0xa67edcec210147b85b589313b05e04c680fdef02";

const FULLY_PROVEN_EVENT = "event FullyProven(address indexed token, uint256 indexed periodId, uint256 totalMinor)";

const fetch = async (options: FetchOptions) => {
const dailyFees = options.createBalances();
const dailySupplySideRevenue = options.createBalances();

// Each FullyProven log = one property/month of proven gross rental income.
const logs = await options.getLogs({
target: REGISTRY,
eventAbi: FULLY_PROVEN_EVENT,
});

for (const log of logs) {
// totalMinor is USD cents -> USD
dailyFees.addUSDValue(Number(log.totalMinor) / 100, "Rental Yield");
dailySupplySideRevenue.addUSDValue(Number(log.totalMinor) / 100, "Rental Yield to Property Holders");
}

// Protocol-retained cut (management fee) not yet quantified on-chain -> 0.
const dailyRevenue = options.createBalances();

return { dailyFees, dailyRevenue, dailySupplySideRevenue };
};

const methodology = {
Fees: "Gross rental income earned by 0xEquity's tokenized real-estate properties, as proven on-chain in the IncomeAttestationRegistry. A month is counted only when it is fully proven by two independent paths (a threshold-signed attestation and a Reclaim zkTLS proof of the same bank statement) that agree on the amount.",
SupplySideRevenue: "All proven rental income, which is distributed to the property-token holders (the suppliers of capital) as yield.",
Revenue: "Protocol-retained management fee. Not yet quantified on-chain; reported as 0 until confirmed.",
};

const breakdownMethodology = {
Fees: {
"Rental Yield": "Gross rental income earned by 0xEquity's tokenized real-estate properties, as proven on-chain in the IncomeAttestationRegistry. A month is counted only when it is fully proven by two independent paths (a threshold-signed attestation and a Reclaim zkTLS proof of the same bank statement) that agree on the amount.",
},
SupplySideRevenue: {
"Rental Yield to Property Holders": "All proven rental income, which is distributed to the property-token holders (the suppliers of capital) as yield.",
},
}
Comment on lines +54 to +61

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding Revenue: {} to breakdownMethodology for completeness.

No labels are added to dailyRevenue so it's not strictly required, but including an empty Revenue entry makes it explicit that revenue is intentionally zero and prevents confusion for future maintainers adding revenue labels.

♻️ Suggested addition
 const breakdownMethodology = {
   Fees: {
     "Rental Yield": "Gross rental income earned by 0xEquity's tokenized real-estate properties, as proven on-chain in the IncomeAttestationRegistry. A month is counted only when it is fully proven by two independent paths (a threshold-signed attestation and a Reclaim zkTLS proof of the same bank statement) that agree on the amount.",
   },
   SupplySideRevenue: {
     "Rental Yield to Property Holders": "All proven rental income, which is distributed to the property-token holders (the suppliers of capital) as yield.",
   },
+  Revenue: {},
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const breakdownMethodology = {
Fees: {
"Rental Yield": "Gross rental income earned by 0xEquity's tokenized real-estate properties, as proven on-chain in the IncomeAttestationRegistry. A month is counted only when it is fully proven by two independent paths (a threshold-signed attestation and a Reclaim zkTLS proof of the same bank statement) that agree on the amount.",
},
SupplySideRevenue: {
"Rental Yield to Property Holders": "All proven rental income, which is distributed to the property-token holders (the suppliers of capital) as yield.",
},
}
const breakdownMethodology = {
Fees: {
"Rental Yield": "Gross rental income earned by 0xEquity's tokenized real-estate properties, as proven on-chain in the IncomeAttestationRegistry. A month is counted only when it is fully proven by two independent paths (a threshold-signed attestation and a Reclaim zkTLS proof of the same bank statement) that agree on the amount.",
},
SupplySideRevenue: {
"Rental Yield to Property Holders": "All proven rental income, which is distributed to the property-token holders (the suppliers of capital) as yield.",
},
Revenue: {},
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fees/0xequity/index.ts` around lines 54 - 61, Add an explicit empty Revenue
section to breakdownMethodology in the 0xEquity fee module for completeness.
Update the breakdownMethodology object alongside Fees and SupplySideRevenue so
it includes Revenue: {} even though dailyRevenue has no labels, making the
intent explicit and easier to maintain.


const adapter: SimpleAdapter = {
version: 2,
pullHourly: true,
fetch,
chains: [CHAIN.BASE],
start: "2026-06-18",
methodology,
breakdownMethodology,
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.

export default adapter;
Loading