Skip to content

Commit

Permalink
Merge pull request #2121 from DefiLlama/fix-opensea
Browse files Browse the repository at this point in the history
Fix opensea
  • Loading branch information
dtmkeng authored Nov 23, 2024
2 parents 94ee03a + a108a2a commit b81e479
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 114 deletions.
36 changes: 7 additions & 29 deletions fees/opensea/index.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,11 @@
import * as sdk from "@defillama/sdk";
import { Adapter, DISABLED_ADAPTER_KEY } from "../../adapters/types";
import type { ChainEndpoints } from "../../adapters/types"
import { Chain } from '@defillama/sdk/build/general';
import { getTimestampAtStartOfDayUTC } from "../../utils/date";
import { CHAIN } from "../../helpers/chains";
import { fetch } from "./seaport";
import { fetch, config } from "./seaport";
import disabledAdapter from "../../helpers/disabledAdapter";

const seaportEndpoints = {
[CHAIN.ETHEREUM]: sdk.graph.modifyEndpoint('kGCuz7xhxMuyRSk8QdnUgijUEqgvhGwkzAVHkbYedCk'),
}

const graphs = (_: ChainEndpoints) => {
return (_: Chain) => {
return async (timestamp: number) => {
const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp);
const fees = await fetch(timestamp);
return {
...fees,
timestamp: todaysTimestamp,
}
};
};
};
const seaportConfig = { fetch, start: '2022-06-12', }

const adapter: Adapter = {
version: 1,
version: 2,
breakdown: {
v1: {
[DISABLED_ADAPTER_KEY]: disabledAdapter,
Expand All @@ -35,12 +15,10 @@ const adapter: Adapter = {
[DISABLED_ADAPTER_KEY]: disabledAdapter,
[CHAIN.ETHEREUM]: disabledAdapter
},
seaport: {
[CHAIN.ETHEREUM]: {
fetch: graphs(seaportEndpoints)(CHAIN.ETHEREUM),
start: '2022-06-12',
},
}
seaport: Object.keys(config).reduce((acc, chain) => {
acc[chain] = seaportConfig
return acc
}, {}),
}
}

Expand Down
122 changes: 37 additions & 85 deletions fees/opensea/seaport.ts
Original file line number Diff line number Diff line change
@@ -1,99 +1,51 @@
import ADDRESSES from '../../helpers/coreAssets.json'
import * as sdk from "@defillama/sdk";
import { getBlock } from "../../helpers/getBlock";
import { getPrices } from "../../utils/prices";
import { CHAIN } from "../../helpers/chains";
import { FetchResultFees } from "../../adapters/types";

interface ILog {
address: string;
data: string;
transactionHash: string;
topics: string[];
}

interface IAmount {
creator_fee: number;
marketplace_fee: number;
isHaveMPFees: boolean;
}

interface IConrtact {
adddress: string;
startBlcok: number;
}
import { FetchOptions, } from "../../adapters/types";

const contract_v1_4 = '0x00000000000001ad428e4906ae43d8f9852d0dd6';
const contract_v1_5 = '0x00000000000000adc04c56bf30ac9d3c0aaf14dc';
const contract_v1_6 = '0x0000000000000068F116a894984e2DB1123eB395';
const defaultSeaports = [contract_v1_4, contract_v1_5, contract_v1_6]
const defaltFeeCollectors = ['0x0000a26b00c1f0df003000390027140000faa719']

const contracts: IConrtact[] = [
{
adddress: contract_v1_4,
startBlcok: 16655960,
},
{
adddress: contract_v1_5,
startBlcok: 17129405,
}
]
const topic0 = '0x9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31';
const event_order_fulfilled = "event OrderFulfilled(bytes32 orderHash, address indexed offerer, address indexed zone, address recipient, (uint8 itemType, address token, uint256 identifier, uint256 amount)[] offer, (uint8 itemType, address token, uint256 identifier, uint256 amount, address recipient)[] consideration)"
const fees_collector = '0x0000a26b00c1f0df003000390027140000faa719';

export const fetch = async (timestamp: number): Promise<FetchResultFees> => {
const fromTimestamp = timestamp - 60 * 60 * 24
const toTimestamp = timestamp
const fromBlock = (await getBlock(fromTimestamp, CHAIN.ETHEREUM, {}));
const toBlock = (await getBlock(toTimestamp, CHAIN.ETHEREUM, {}));
const logs: ILog[] = (await Promise.all(contracts.filter(e => e.startBlcok <= fromBlock).map((contract: IConrtact) => sdk.getEventLogs({
target: contract.adddress,
toBlock: toBlock,
fromBlock: fromBlock,
chain: CHAIN.ETHEREUM,
topics: [topic0]
})))).flat() as ILog[];
export const config = {
ethereum: {
fees_collectors: [...defaltFeeCollectors, '0x31314e41E743A638FD485d537F4a2B5F57D662bb', '0x1208e7F7AED9d39Ed25ef582B8933e4a1D0DA6af']
},
arbitrum: {},
avax: {},
base: {},
blast: {},
klaytn: {},
optimism: {},
polygon: {},
zora: {},
}

const fes_raw: IAmount[] = logs.filter(e => e.data.length === 1602)
.map((e: ILog) => {
const data = e.data.replace('0x', '');
const fees_1 = Number('0x' + data.slice(18 * 64, (18 * 64) + 64)) / 10 ** 18;
const address_1 = data.slice((19 * 64), (19 * 64) + 64);
const contract_address_1 = '0x' + address_1.slice(24, address_1.length);
export const fetch = async ({ createBalances, getLogs, chain, }: FetchOptions) => {
const dailyFees = createBalances()
const dailyRevenue = createBalances()
const { seaports = defaultSeaports, fees_collectors = defaltFeeCollectors } = config[chain]
const feeCollectorSet = new Set(fees_collectors.map(i => i.toLowerCase()));

const fees_2 = Number('0x' + data.slice(23 * 64, (23 * 64) + 64)) / 10 ** 18;
const address_2 = data.slice((24 * 64), (24 * 64) + 64);
const contract_address_2 = '0x' + address_2.slice(24, address_2.length);
const min = Math.min(fees_1, fees_2);
const max = Math.max(fees_1, fees_2);
const isHaveMPFees = [contract_address_1.toLowerCase(), contract_address_2.toLowerCase()].includes(fees_collector.toLowerCase());
return {
creator_fee: max,
marketplace_fee: min,
isHaveMPFees
}
})
const logs = await getLogs({ targets: seaports, eventAbi: event_order_fulfilled, })

const marketplace_fee = fes_raw
.filter(e => e.isHaveMPFees)
.map(e => e.marketplace_fee as number)
.filter((e) => !isNaN(e))
.filter(e => e < 100)
.reduce((a: number, b: number) => a + b, 0)
logs.forEach(log => {
const recipients = log.consideration.filter((i: any) => +i.itemType.toString() < 2) // exclude NFTs (ERC721 and ERC1155)
if (recipients.length < 2) return;
const biggestValue = recipients.reduce((a: any, b: any) => a.amount > b.amount ? a : b)

const creator_fee = fes_raw.map(e => e.creator_fee as number)
.filter((e) => !isNaN(e))
.filter(e => e < 100)
.reduce((a: number, b: number) => a + b, 0)
recipients.forEach((consideration: any) => {
if (consideration.recipient === biggestValue.recipient) return; // this is sent to the NFT owner, rest are fees
dailyFees.add(consideration.token, consideration.amount)
if (feeCollectorSet.has(consideration.recipient.toLowerCase())) {
dailyRevenue.add(consideration.token, consideration.amount)
}
})
})

const fees = (marketplace_fee + creator_fee);
const rev = (marketplace_fee);
const ethAddress = "ethereum:" + ADDRESSES.null;
const ethPrice = (await getPrices([ethAddress], timestamp))[ethAddress].price;
const dailyFees = (fees * ethPrice)
const dailyRevenue = (rev * ethPrice)
return {
dailyFees: `${dailyFees}`,
dailyRevenue: `${dailyRevenue}`,
timestamp
dailyFees, dailyRevenue,
}

}

0 comments on commit b81e479

Please sign in to comment.