Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensuro: removes deprecated pools and adds new ones #1512

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
127 changes: 85 additions & 42 deletions src/adaptors/ensuro/index.js
Original file line number Diff line number Diff line change
@@ -1,65 +1,108 @@
const sdk = require('@defillama/sdk');
const { getProvider } = require('@defillama/sdk/build/general');
const ethers = require('ethers');
const axios = require('axios');

// Idea of using alchemyKey copied from ../mellow-yield/index.js, but now with better code
const alchemy_url_regex = /https:[/][/].*alchemy[.]com[/]v2[/]([^/]+)/g;

const extractKey = (alchemy_full_url) => {
console.log('alchemy_full_url', alchemy_full_url);
const match = alchemy_url_regex.exec(alchemy_full_url);
if (match === null) return null;
console.log('match', match, match[1]);
return match[1];
};

const addressBook = {
polygon: {
usdc: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
usdc: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
eTokens: [
// eTokens
{name: "eToken Junior Koala", address: "0x8d2Ee82c4172B2138B06b8037d769cBfAf9C0274", symbol: "eUSDJrKo"},
{name: "eToken Senior", address: "0x55bAe6690d46EA94D7F05DF7c80A85E322421fB6", symbol: "eUSDSr"},
{name: "eToken Innov Zone", address: "0x1C48Accaf6f8106883AA1973A45F02525652DEfC", symbol: "eUSDJrIZ"},
// Commenting out these two pools, since they aren't open to the general public for now
// {name: "eToken Junior Koala BMA", address: "0xBC33c283A37d46ABA17BC5F8C27b27242688DeC6", symbol: "eUSDJrKoBMA"},
// {name: "eToken Senior BMA", address: "0xF383eF2D31E1d4a19B3e04ca2937DB6A8DA9f229", symbol: "eUSDSrBMA"},
{
name: 'Jr Koala BMA',
address: '0xBC33c283A37d46ABA17BC5F8C27b27242688DeC6',
symbol: 'eUSDCKoBMAJr',
},
{
name: 'Sr BMA',
address: '0xF383eF2D31E1d4a19B3e04ca2937DB6A8DA9f229',
symbol: 'eUSDCBMASr',
},
{
name: 'Jr Spot BMA',
address: '0x6229D78658305a301E177f9dAEa3a0799fd1528C',
symbol: 'eUSDCGSJr',
},
],
}
},
};

const abiTransfer = ["event Transfer(address indexed from, address indexed to, uint256 value)"];
const abiTransfer = [
'event Transfer(address indexed from, address indexed to, uint256 value)',
];

const getApy = async () => {
const timestamp1dayAgo = Math.floor(Date.now() / 1000) - 86400;
const block1dayAgo = (
await axios.get(`https://coins.llama.fi/block/polygon/${timestamp1dayAgo}`)
).data.height;

const provider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_CONNECTION_POLYGON);
const alchemyKey = extractKey(process.env.ALCHEMY_CONNECTION_ETHEREUM || '');

if (alchemyKey === null)
throw new Error(
'Environment variable ALCHEMY_CONNECTION_ETHEREUM not defined or not in the expected format'
);
const provider = new ethers.providers.AlchemyProvider('matic', alchemyKey);

return await Promise.all(addressBook.polygon.eTokens.map(async (etk) => {
const [tsNow, tsOneDayAgo] = await Promise.all([
sdk.api.erc20.totalSupply({ target: etk.address, chain: "polygon" }),
sdk.api.erc20.totalSupply({ target: etk.address, chain: "polygon", block: block1dayAgo }),
]);
return await Promise.all(
addressBook.polygon.eTokens.map(async (etk) => {
const [tsNow, tsOneDayAgo] = await Promise.all([
sdk.api.erc20.totalSupply({ target: etk.address, chain: 'polygon' }),
sdk.api.erc20.totalSupply({
target: etk.address,
chain: 'polygon',
block: block1dayAgo,
}),
]);

const contract = new ethers.Contract(etk.address, abiTransfer, provider);
const transfers = await contract.queryFilter(contract.filters.Transfer(), block1dayAgo);
const netDeposits = transfers.filter((evt) => (
evt.args.from === ethers.constants.AddressZero ||
evt.args.to === ethers.constants.AddressZero
)).reduce((accumulator, evt) => (
evt.args.from === ethers.constants.AddressZero ?
accumulator.add(evt.args.value) :
accumulator.sub(evt.args.value)
), ethers.BigNumber.from(0)).toNumber();
console.log(netDeposits);
console.log(tsNow.output);
const dailyApr = (tsNow.output - tsOneDayAgo.output - netDeposits) / tsOneDayAgo.output;
// Using apr to apy formula from https://www.aprtoapy.com/
const apy = (Math.pow(1 + dailyApr, 365) - 1) * 100;
return {
pool: etk.address,
chain: 'polygon',
project: 'ensuro',
symbol: etk.symbol,
tvlUsd: tsNow.output / 1e6,
apyBase: apy,
url: `https://app.ensuro.co/eTokens/${etk.address}`,
underlyingTokens: [addressBook.polygon.usdc],
};
}));
const contract = new ethers.Contract(etk.address, abiTransfer, provider);
const transfers = await contract.queryFilter(
contract.filters.Transfer(),
block1dayAgo
);
const netDeposits = transfers
.filter(
(evt) =>
evt.args.from === ethers.constants.AddressZero ||
evt.args.to === ethers.constants.AddressZero
)
.reduce(
(accumulator, evt) =>
evt.args.from === ethers.constants.AddressZero
? accumulator.add(evt.args.value)
: accumulator.sub(evt.args.value),
ethers.BigNumber.from(0)
)
.toNumber();
console.log(netDeposits);
console.log(tsNow.output);
const dailyApr =
(tsNow.output - tsOneDayAgo.output - netDeposits) / tsOneDayAgo.output;
// Using apr to apy formula from https://www.aprtoapy.com/
const apy = (Math.pow(1 + dailyApr, 365) - 1) * 100;
return {
pool: etk.address,
chain: 'polygon',
project: 'ensuro',
symbol: etk.symbol,
tvlUsd: tsNow.output / 1e6,
apyBase: apy,
url: `https://app.ensuro.co/eTokens/${etk.address}`,
underlyingTokens: [addressBook.polygon.usdc],
};
})
);
};

module.exports = {
Expand Down
Loading