Skip to content
Closed
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
76 changes: 76 additions & 0 deletions dexs/o2/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { FetchOptions, SimpleAdapter } from "../../adapters/types";
import { CHAIN } from "../../helpers/chains";
import { queryDuneSql } from "../../helpers/dune";
import axios from "axios";

const ApiBaseUrl = "https://api.o2.app";
const FeeRecipient =
"0x18af30EfA58A70042013192bBDdF8A21221004b44cC1cbA1A0038cE524aAa2EE";

const fetch = async (options: FetchOptions) => {
const markets = await axios.get(ApiBaseUrl.concat("/v1/markets"));

const orderbookContractIds = markets.data.markets.map(
(market) => market.contract_id,
);

const dailyVolume = options.createBalances();
const dailyFees = options.createBalances();

const combinedQuery = `
SELECT
SUM(CAST(amount AS DECIMAL(38,0))) as amount,
asset_id
FROM fuel.receipts
WHERE contract_id IN (${orderbookContractIds})
AND to = ${FeeRecipient}
AND block_time >= FROM_UNIXTIME(${options.startTimestamp})
AND block_time < FROM_UNIXTIME(${options.endTimestamp})
GROUP BY asset_id
`;

const [duneResults, volumeResults] = await Promise.all([
queryDuneSql(options, combinedQuery),
axios
.get(
`${ApiBaseUrl}/defillama/v1/volumes?from=${options.startTimestamp}&to=${options.endTimestamp}`,
)
.then((res) => res.data)
.catch(() => []),
]);

if (duneResults?.length > 0) {
duneResults.forEach((row) => {
dailyFees.add(row.asset_id, row.amount);
});
}

volumeResults.forEach((result) => {
dailyVolume.add(result.base_asset_id, result.base_volume);
});

return {
dailyVolume,
dailyFees,
dailyProtocolRevenue: dailyFees,
dailyRevenue: dailyFees,
};
};

const methodology = {
Fees: "All fees paid by users on the O2 Exchange",
Revenue: "Fees are distributed to Fuel Labs",
ProtocolRevenue: "Fees are distributed to Fuel Labs",
Volume:
"The volume is calculated based on the amount of assets entering the orderbooks",
};

const adapter: SimpleAdapter = {
version: 2,
fetch,
chains: [CHAIN.FUEL],
start: "2025-12-1",
methodology,
};

export default adapter;
Loading