Skip to content

Commit 3cf0182

Browse files
wegoryGreg T
andauthored
Update for base token swap to PYUSD (#17907)
Co-authored-by: Greg T <[email protected]>
1 parent cd88602 commit 3cf0182

File tree

1 file changed

+105
-77
lines changed

1 file changed

+105
-77
lines changed

projects/usdai/index.js

Lines changed: 105 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
const abi = {
2-
"claimableBaseYield": "uint256:claimableBaseYield",
3-
"pools": "address[]:pools",
4-
"currencyToken": "address:currencyToken",
5-
"liquidityNodes": "function liquidityNodes(uint128 startTick, uint128 endTick) view returns (tuple(uint128 tick, uint128 value, uint128 shares, uint128 available, uint128 pending, uint128 redemptions, uint128 prev, uint128 next)[])",
6-
"whitelistedTokens": "function whitelistedTokens() external view returns (address[] memory)",
7-
"loanRouterBalances": "function loanRouterBalances() external view returns (uint256, uint256, uint256)",
8-
"loanState": "function loanState(bytes32 loanTermsHash) external view returns (uint8, uint64, uint64, uint256)"
9-
};
2+
"claimableBaseYield": "uint256:claimableBaseYield",
3+
"pools": "address[]:pools",
4+
"currencyToken": "address:currencyToken",
5+
"liquidityNodes": "function liquidityNodes(uint128 startTick, uint128 endTick) view returns (tuple(uint128 tick, uint128 value, uint128 shares, uint128 available, uint128 pending, uint128 redemptions, uint128 prev, uint128 next)[])",
6+
"whitelistedTokens": "function whitelistedTokens() external view returns (address[] memory)",
7+
"loanRouterBalances": "function loanRouterBalances() external view returns (uint256, uint256, uint256)",
8+
"loanState": "function loanState(bytes32 loanTermsHash) external view returns (uint8, uint64, uint64, uint256)",
9+
"baseYieldAccrued": "function baseYieldAccrued() external view returns (uint256)"
10+
};
1011
const { sumTokens2 } = require("../helper/unwrapLPs");
1112
const { gql, request } = require("graphql-request");
1213

@@ -18,9 +19,11 @@ const STAKED_USDAI_CONTRACT = "0x0B2b2B2076d95dda7817e785989fE353fe955ef9";
1819
const QUEUED_DEPOSITOR_CONTRACT = "0x81cc0DEE5e599784CBB4862c605c7003B0aC5A53";
1920
const LOAN_ROUTER_CONTRACT = "0x0C2ED170F2bB1DF1a44292Ad621B577b3C9597D1";
2021
const WRAPPED_M_CONTRACT = "0x437cc33344a0B27A429f795ff6B469C72698B291";
22+
const PYUSD = "0x46850aD61C2B7d64d08c9C754F45254596696984";
2123
const USDC = "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";
2224
const USDT = "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9";
23-
const LOAN_TOKENS = [USDC, USDT];
25+
const WHITELISTED_TOKENS = [USDC, USDT, PYUSD];
26+
const LOAN_TOKENS = [USDC, USDT, PYUSD];
2427
const LEGACY_POOL_1 = "0x0f62b8C58E1039F246d69bA2215ad5bF0D2Bb867";
2528
const LEGACY_POOL_2 = "0xcd9d510c4e2fe45e6ed4fe8a3a30eeef3830cc14";
2629
const LEGACY_POOLS = [LEGACY_POOL_1, LEGACY_POOL_2];
@@ -58,99 +61,124 @@ async function tvl(api) {
5861
// Add wrapped M balance in USDai
5962
api.add(WRAPPED_M_CONTRACT, wrappedMBalanceInUsdai);
6063

64+
// Get PYUSD balance in USDai
65+
const pyusdBalanceInUsdai = await api.call({
66+
target: PYUSD,
67+
abi: 'erc20:balanceOf',
68+
params: [USDAI_CONTRACT],
69+
})
70+
71+
// Add PYUSD balance in USDai
72+
api.add(PYUSD, pyusdBalanceInUsdai);
73+
6174
// Get wrapped M tokens in Staked USDai
6275
const wrappedMBalanceInStakedUsdai = await api.call({
63-
target: WRAPPED_M_CONTRACT,
64-
abi: 'erc20:balanceOf',
65-
params: [STAKED_USDAI_CONTRACT],
76+
target: WRAPPED_M_CONTRACT,
77+
abi: 'erc20:balanceOf',
78+
params: [STAKED_USDAI_CONTRACT],
6679
})
67-
80+
6881
// Add wrapped M balance in Staked USDai
6982
api.add(WRAPPED_M_CONTRACT, wrappedMBalanceInStakedUsdai);
7083

71-
// Immediately claimable wrapped M tokens
72-
const claimableWrappedM = await api.call({
73-
target: STAKED_USDAI_CONTRACT,
74-
abi: abi.claimableBaseYield // return value is scaled up by 10^12
75-
}) / 10 ** 12; // scale down by 10^12 to match the decimals of the wrapped M token
84+
// Claimable wrapped M tokens (to be phased out)
85+
try {
86+
const claimableWrappedM = await api.call({
87+
target: STAKED_USDAI_CONTRACT,
88+
abi: abi.claimableBaseYield // return value is scaled up by 10^12
89+
});
90+
const scaledClaimableWrappedM = BigInt(claimableWrappedM) / (10n ** 12n); // scale down by 10^12 to match wrapped M decimals
91+
92+
// Add claimable wrapped M tokens
93+
api.add(WRAPPED_M_CONTRACT, scaledClaimableWrappedM)
94+
} catch (error) {
95+
console.error(error);
96+
}
97+
98+
// Claimable PYUSD (scaled down by 10^12 to match the decimals of the PYUSD token)
99+
const claimablePyusd = await api.call({
100+
target: USDAI_CONTRACT,
101+
abi: abi.baseYieldAccrued,
102+
});
103+
const scaledClaimablePyusd = BigInt(claimablePyusd) / BigInt(10 ** 12);
76104

77-
// Add claimable wrapped M tokens
78-
api.add(WRAPPED_M_CONTRACT, claimableWrappedM)
105+
// Add claimable PYUSD
106+
api.add(PYUSD, scaledClaimablePyusd);
79107

80108
// Get loan repayment balances in Staked USDai
81109
await sumTokens2({
82110
api,
83-
owner: STAKED_USDAI_CONTRACT,
111+
owner: STAKED_USDAI_CONTRACT,
84112
tokens: LOAN_TOKENS,
85113
permitFailure: true,
86114
})
87115

88116
// Add tokens held by the queued depositor
89-
const whitelistedTokens = await api.call({
90-
target: QUEUED_DEPOSITOR_CONTRACT,
91-
abi: abi.whitelistedTokens,
92-
});
93117
await sumTokens2({
94118
api,
95-
owner: QUEUED_DEPOSITOR_CONTRACT,
96-
tokens: whitelistedTokens,
119+
owner: QUEUED_DEPOSITOR_CONTRACT,
120+
tokens: WHITELISTED_TOKENS,
97121
permitFailure: true,
98122
})
99123
}
100124

101125
async function borrowed(api) {
102-
// Legacy pools
103-
const tokens = await api.multiCall({ abi: abi.currencyToken, calls: LEGACY_POOLS, permitFailure: true });
104-
const tokenDecimals = await api.multiCall({
105-
abi: "erc20:decimals",
106-
calls: tokens.map((token) => ({ target: token })),
126+
// Legacy pools
127+
const tokens = await api.multiCall({ abi: abi.currencyToken, calls: LEGACY_POOLS, permitFailure: true });
128+
const tokenDecimals = await api.multiCall({
129+
abi: "erc20:decimals",
130+
calls: tokens.map((token) => ({ target: token })),
131+
permitFailure: true,
132+
});
133+
const decimalsMap = {};
134+
tokens.forEach((token, index) => {
135+
decimalsMap[token] = tokenDecimals[index];
136+
});
137+
const poolsBorrowedValue = (
138+
await api.multiCall({
139+
abi: abi.liquidityNodes,
140+
calls: LEGACY_POOLS.map((pool) => ({
141+
target: pool,
142+
params: [0, MAX_UINT_128],
143+
})),
107144
permitFailure: true,
108-
});
109-
const decimalsMap = {};
110-
tokens.forEach((token, index) => {
111-
decimalsMap[token] = tokenDecimals[index];
112-
});
113-
const poolsBorrowedValue = (
114-
await api.multiCall({
115-
abi: abi.liquidityNodes,
116-
calls: LEGACY_POOLS.map((pool) => ({
117-
target: pool,
118-
params: [0, MAX_UINT_128],
119-
})),
120-
permitFailure: true,
121-
})
122-
).map((liquidityNodes, poolIndex) => {
123-
const token = tokens[poolIndex];
124-
const decimals = decimalsMap[token];
125-
const scalingFactor = 10 ** (18 - decimals);
126-
127-
return liquidityNodes.reduce((partialSum, node) => {
128-
const scaledValue = (+node.value - +node.available) / scalingFactor;
129-
return partialSum + scaledValue;
130-
}, 0);
131-
});
132-
api.addTokens(tokens, poolsBorrowedValue);
145+
})
146+
).map((liquidityNodes, poolIndex) => {
147+
const token = tokens[poolIndex];
148+
const decimals = decimalsMap[token];
149+
if (decimals == null || !liquidityNodes) return 0;
150+
const scalingFactor = 10 ** (18 - decimals);
151+
152+
return liquidityNodes.reduce((partialSum, node) => {
153+
const scaledValue = (+node.value - +node.available) / scalingFactor;
154+
return partialSum + scaledValue;
155+
}, 0);
156+
});
157+
api.addTokens(tokens, poolsBorrowedValue);
133158

134-
// Loan router borrowed
135-
const { loanRouterEvents } = await request(LOAN_ROUTER_SUBGRAPH_API, loanHashesQuery, {
136-
timestampLte: String(api.timestamp),
137-
});
138-
for (const event of loanRouterEvents) {
139-
// Get the currency token
140-
const { currencyToken } = event.loanOriginated;
141-
142-
// Get scaled balance
143-
const [status, , , scaledBalance] = await api.call({ abi: abi.loanState, target: LOAN_ROUTER_CONTRACT, params: [event.loanTermsHash] });
159+
// Loan router borrowed
160+
const { loanRouterEvents } = await request(LOAN_ROUTER_SUBGRAPH_API, loanHashesQuery, {
161+
timestampLte: String(api.timestamp),
162+
});
163+
for (const event of loanRouterEvents) {
164+
// Get the currency token
165+
const { currencyToken } = event.loanOriginated;
144166

145-
// If the loan is inactive, continue
146-
if (status !== "1") continue;
167+
// Get scaled balance
168+
const [status, , , scaledBalance] = await api.call({ abi: abi.loanState, target: LOAN_ROUTER_CONTRACT, params: [event.loanTermsHash] });
147169

148-
// Scale down by the decimals of the currency token
149-
const unscaledBalance = scaledBalance / 10 ** (18 - currencyToken.decimals);
170+
// If the loan is inactive, continue
171+
if (+status !== 1) continue;
150172

151-
// Add the balance to the TVL
152-
api.add(currencyToken.id, unscaledBalance);
153-
}
173+
// If the currency token has more than 18 decimals, continue
174+
if (currencyToken.decimals > 18) continue;
175+
176+
// Scale down by the decimals of the currency token
177+
const unscaledBalance = BigInt(scaledBalance) / BigInt(10 ** (18 - currencyToken.decimals));
178+
179+
// Add the balance to the TVL
180+
api.add(currencyToken.id, unscaledBalance);
181+
}
154182
}
155183

156184
module.exports = {
@@ -159,9 +187,9 @@ module.exports = {
159187
borrowed,
160188
},
161189
methodology:
162-
"TVL is calculated by summing the value of tokens held by the protocol and outstanding immediately claimable yield.",
190+
"TVL is calculated by summing the value of tokens held by the protocol and outstanding claimable yield.",
163191
hallmarks: [
164-
[1757548800, "Deposit Caps raised to $250M"],
165-
[1758758400, "Deposit Caps raised to $500M"]
192+
["2025-09-12", "Deposit Caps raised to $250M"],
193+
["2025-09-26", "Deposit Caps raised to $500M"]
166194
],
167195
};

0 commit comments

Comments
 (0)