Skip to content

Commit

Permalink
feat(SpellStaking): Add support for Blast and Kava
Browse files Browse the repository at this point in the history
  • Loading branch information
0xmDreamy committed Aug 14, 2024
1 parent 0271e81 commit 09757e9
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 54 deletions.
1 change: 1 addition & 0 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
| MagicGlp Arbitrum | [task](https://app.gelato.network/functions/task/0x46cdddc42edb01fb462cb22efd2578d22351629689b00434531df2e254665279:42161) |
| MagicGlp Avalanche | [task](https://app.gelato.network/functions/task/0x36ee967b80c68152c0af1c69d49ff60f0eb41264f3cebc4dcc8b16843c7038be:43114) |
| SpellSwapper | [task](https://app.gelato.network/functions/task/0x9d6f1f55569bf50b6273f4e1b6a75fc64d8cd906d7c401d501f207f19120e3a0:1) |
| SpellStaking Blast | [task](https://app.gelato.network/functions/task/0xd6b36b19af229cc7291882eac23c45741ef962d1f58d9c5b37ef4ff6a5cf12ce:81457) |
| Velodrome vOP/USDC | [task](https://app.gelato.network/functions/task/0x1593a557fbbccc9b8c41f175b059eac993a508e9c104036a1bb93f23b1e5d1e1:10) |
| WBTC InterestStrategy | [task](https://app.gelato.network/functions/task/0xdbf9b9d3f40c0c5a44fed95d0d8b1a7ec70882f56e5c3f64a67b4963ca144775:1) |
| WETH InterestStrategy | [task](https://app.gelato.network/functions/task/0x49b5af6155b652aa036b3cf22f798f14384aa4b124cb9780ac3141389b00e311:1) |
Expand Down
6 changes: 6 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const config = {
"ethereum",
"avalanche",
"arbitrum",
"blast",
"fantom",
"optimism",
"polygon",
Expand Down Expand Up @@ -49,6 +50,11 @@ const config = {
url: "https://arb1.arbitrum.io/rpc",
accounts: [PRIVATE_KEY],
},
blast: {
chainId: 81457,
url: "https://rpc.ankr.com/blast ",
accounts: [PRIVATE_KEY],
},
fantom: {
chainId: 250,
url: "https://rpc2.fantom.network",
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
"url": "https://github.com/Abracadabra-money/web3-functions",
"private": false,
"scripts": {
"build": "bun run clean && bun run install && npx tsc",
"build": "bun run clean && bun run install && tsc",
"clean": "rm -rf dist",
"typecheck": "tsc --noEmit",
"lint": "biome check",
"lint:fix": "biome check --write",
"lint:ci": "biome ci",
"run-task": "concurrently -m 1 \"bun:run-task:*(!run-task:[^:]+:)\"",
"create-task:gm": "hardhat run ./scripts/create-gm-task.ts --network ethereum",
"create-task:spell-staking": "killall -9 anvil; hardhat run ./scripts/create-spell-staking-task.ts --network anvil",
"create-task:spell-staking": "hardhat run ./scripts/create-spell-staking-task.ts",
"create-task:magiclvl": "hardhat run ./scripts/create-magiclvl-task.ts --network anvil",
"create-task:process-locks": "hardhat run ./scripts/create-process-locks-task.ts --network arbitrum",
"create-task:spell-swapper": "hardhat run ./scripts/create-spell-swapper-task.ts --network ethereum",
Expand All @@ -30,7 +30,9 @@
"run-task:spell-staking:mainnet": "hardhat w3f-run spell-staking --logs --network ethereum",
"run-task:spell-staking:avalanche": "hardhat w3f-run spell-staking --logs --network avalanche",
"run-task:spell-staking:arbitrum": "hardhat w3f-run spell-staking --logs --network arbitrum",
"run-task:spell-staking:blast": "hardhat w3f-run spell-staking --logs --network blast",
"run-task:spell-staking:fantom": "hardhat w3f-run spell-staking --logs --network fantom",
"run-task:spell-staking:kava": "hardhat w3f-run spell-staking --logs --network kava",
"run-task:gm": "hardhat w3f-run gm --logs --network arbitrum",
"run-task:magiclvl": "hardhat w3f-run magiclvl --logs --network bsc",
"run-task:process-locks": "concurrently --kill-others-on-fail -m 1 bun:run-task:process-locks:*",
Expand Down
2 changes: 1 addition & 1 deletion scripts/create-spell-staking-task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const main = async () => {
console.log();
}

const ALTCHAIN_IDS = [250, 43114, 42161];
const ALTCHAIN_IDS = [250, 43114, 42161, 81457] as const;

for (const chainId of ALTCHAIN_IDS) {
console.log(`Creating ChainId ${chainId} Task`);
Expand Down
2 changes: 2 additions & 0 deletions utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ export const ARBITRUM_SPELL =
"0x3e6648c5a70a150a88bce65f4ad4d506fe15d2af" as const satisfies Address;
export const ARBITRUM_OPS_SAFE =
"0xA71A021EF66B03E45E0d85590432DFCfa1b7174C" as const satisfies Address;
export const GELATO_PROXY =
"0x4D0c7842cD6a04f8EDB39883Db7817160DA159C3" as const satisfies Address;
131 changes: 80 additions & 51 deletions web3-functions/spell-staking/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
type Web3FunctionContext,
} from "@gelatonetwork/web3-functions-sdk";
import { BigNumber, Contract, utils } from "ethers";
import { GELATO_PROXY } from "../../utils/constants";
import { LZ_CHAIN_IDS } from "../../utils/lz";
import { SimulationUrlBuilder } from "../../utils/tenderly";

Expand Down Expand Up @@ -38,8 +39,10 @@ const MSPELL_STAKING_ADDRESSES: { [chainId: number]: string } = {
const MIM_ADDRESSES: { [chainId: number]: string } = {
1: "0x99D8a9C45b2ecA8864373A26D1459e3Dff1e17F3", // Ethereum
250: "0x82f0B8B456c1A451378467398982d4834b6829c1", // Fantom
2222: "0x471EE749bA270eb4c1165B5AD95E614947f6fCeb", // Kava
43114: "0x130966628846BFd36ff31a822705796e8cb8C18D", // Avalanche
42161: "0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A", // Arbitrum
81457: "0x76DA31D7C9CbEAE102aff34D3398bC450c8374c1", // Blast
};
const SPELL_ADDRESSES: { [chainId: number]: string } = {
1: "0x090185f2135308BaD17527004364eBcC2D37e5F6", // Ethereum
Expand All @@ -48,8 +51,13 @@ const SPELL_ADDRESSES: { [chainId: number]: string } = {
42161: "0x3E6648C5a70A150A88bCE65F4aD4d506Fe15d2AF", // Arbitrum
};

const WITHDRAWER_ADDRESS_LEGACY =
"0x2C9f65BD1a501CB406584F5532cE57c28829B131" as const;
const WITHDRAWER_ADDRESS_LATEST =
"0x22d0e6A4e9b658184248f5e0BF89A0D763849544" as const;

const MAINNET_ADDRESSES = {
withdrawer: "0x2C9f65BD1a501CB406584F5532cE57c28829B131",
withdrawer: WITHDRAWER_ADDRESS_LEGACY,
distributor: "0x953DAb0e64828972853E7faA45634620A40Fa479",
sSpell: "0x26FA3fFFB6EfE8c1E69103aCb4044C26B9A106a9",
treasury: "0xDF2C270f610Dc35d8fFDA5B453E74db5471E126B",
Expand Down Expand Up @@ -80,20 +88,25 @@ Web3Function.onRun(async (context: Web3FunctionContext) => {
const WITHDRAWER_INTERFACE = new utils.Interface(WITHDRAWER_ABI);
const DISTRIBUTOR_INTERFACE = new utils.Interface(DISTRIBUTOR_ABI);

// same address on all chains
const WITHDRAWER_ADDRESS = "0x2C9f65BD1a501CB406584F5532cE57c28829B131";
const ALTCHAIN_IDS = [250, 2222, 43114, 42161, 81457] as const;
const CHAIN_IDS = [1, ...ALTCHAIN_IDS] as const;

// supported chains
const ALTCHAIN_IDS = [250, 43114, 42161];
const CHAIN_IDS = [1, ...ALTCHAIN_IDS];
const WITHDRAWER_ADDRESS = {
1: WITHDRAWER_ADDRESS_LEGACY,
250: WITHDRAWER_ADDRESS_LEGACY,
2222: WITHDRAWER_ADDRESS_LATEST,
42161: WITHDRAWER_ADDRESS_LEGACY,
43114: WITHDRAWER_ADDRESS_LEGACY,
81457: WITHDRAWER_ADDRESS_LATEST,
} as const satisfies Record<(typeof CHAIN_IDS)[number], string>;

/////////////////////////////////////////////////
// Initialization
/////////////////////////////////////////////////
const info: {
[chainId: number]: {
withdrawer: Contract;
spell: Contract;
spell: Contract | undefined;
mSpellStakedAmount: BigNumber;
sSpellStakedAmount: BigNumber;
};
Expand All @@ -103,8 +116,15 @@ Web3Function.onRun(async (context: Web3FunctionContext) => {
const provider = multiChainProvider.chainId(chainId);

info[chainId] = {
withdrawer: new Contract(WITHDRAWER_ADDRESS, WITHDRAWER_ABI, provider),
spell: new Contract(SPELL_ADDRESSES[chainId], IERC20_ABI, provider),
withdrawer: new Contract(
WITHDRAWER_ADDRESS[chainId],
WITHDRAWER_ABI,
provider,
),
spell:
SPELL_ADDRESSES[chainId] !== undefined
? new Contract(SPELL_ADDRESSES[chainId], IERC20_ABI, provider)
: undefined,
mSpellStakedAmount: BigNumber.from(0),
sSpellStakedAmount: BigNumber.from(0),
};
Expand Down Expand Up @@ -158,24 +178,27 @@ Web3Function.onRun(async (context: Web3FunctionContext) => {
// Fetch staked amounts
await Promise.all(
CHAIN_IDS.map(async (chainId) => {
// mSPELL staked amount
info[chainId].mSpellStakedAmount = await info[chainId].spell.balanceOf(
MSPELL_STAKING_ADDRESSES[chainId],
);

// sSPELL staked amount (mainnet only)
if (chainId === MAINNET_CHAIN_ID) {
info[chainId].sSpellStakedAmount = await info[
chainId
].spell.balanceOf(MAINNET_ADDRESSES.sSpell);
const spellContract = info[chainId].spell;
if (spellContract !== undefined) {
// mSPELL staked amount
info[chainId].mSpellStakedAmount = await spellContract.balanceOf(
MSPELL_STAKING_ADDRESSES[chainId],
);

// sSPELL staked amount (mainnet only)
if (chainId === MAINNET_CHAIN_ID) {
info[chainId].sSpellStakedAmount = await spellContract.balanceOf(
MAINNET_ADDRESSES.sSpell,
);
totalSpellStaked = totalSpellStaked.add(
info[chainId].sSpellStakedAmount,
);
}

totalSpellStaked = totalSpellStaked.add(
info[chainId].sSpellStakedAmount,
info[chainId].mSpellStakedAmount,
);
}

totalSpellStaked = totalSpellStaked.add(
info[chainId].mSpellStakedAmount,
);
}),
);

Expand Down Expand Up @@ -223,30 +246,32 @@ Web3Function.onRun(async (context: Web3FunctionContext) => {
});

// AltChain allocations
for (const chainId in ALTCHAIN_IDS) {
const amountToBridge = mimBalanceInDistributor
.mul(info[ALTCHAIN_IDS[chainId]].mSpellStakedAmount)
.div(totalSpellStaked);

// Estimate bridging fee
const { fee, gas } = await distributorMainnet.estimateBridgingFee(
amountToBridge.toString(),
LZ_CHAIN_IDS[ALTCHAIN_IDS[chainId]],
MSPELL_STAKING_ADDRESSES[ALTCHAIN_IDS[chainId]],
); // use default minDstGasLookup

distributions.push({
recipient: MSPELL_STAKING_ADDRESSES[ALTCHAIN_IDS[chainId]],
gas: gas.toString(),
lzChainId: LZ_CHAIN_IDS[ALTCHAIN_IDS[chainId]].toString(),
fee: fee.toString(),
amount: amountToBridge.toString(),
});
for (const chainId of ALTCHAIN_IDS) {
if (info[chainId].spell !== undefined) {
const amountToBridge = mimBalanceInDistributor
.mul(info[chainId].mSpellStakedAmount)
.div(totalSpellStaked);

// Estimate bridging fee
const { fee, gas } = await distributorMainnet.estimateBridgingFee(
amountToBridge.toString(),
LZ_CHAIN_IDS[chainId],
MSPELL_STAKING_ADDRESSES[chainId],
); // use default minDstGasLookup

distributions.push({
recipient: MSPELL_STAKING_ADDRESSES[chainId],
gas: gas.toString(),
lzChainId: LZ_CHAIN_IDS[chainId].toString(),
fee: fee.toString(),
amount: amountToBridge.toString(),
});
}
}

// withdraw
callData.push({
to: WITHDRAWER_ADDRESS,
to: MAINNET_ADDRESSES.withdrawer,
data: WITHDRAWER_INTERFACE.encodeFunctionData("withdraw", []),
});

Expand All @@ -273,13 +298,17 @@ Web3Function.onRun(async (context: Web3FunctionContext) => {

// withdraw
callData.push({
to: WITHDRAWER_ADDRESS,
to: WITHDRAWER_ADDRESS[
gelatoArgs.chainId as keyof typeof WITHDRAWER_ADDRESS
],
data: WITHDRAWER_INTERFACE.encodeFunctionData("withdraw", []),
});

// bridge
callData.push({
to: WITHDRAWER_ADDRESS,
to: WITHDRAWER_ADDRESS[
gelatoArgs.chainId as keyof typeof WITHDRAWER_ADDRESS
],
data: WITHDRAWER_INTERFACE.encodeFunctionData("bridge", [
mimBalanceInDistributor,
fee,
Expand Down Expand Up @@ -318,11 +347,11 @@ Web3Function.onRun(async (context: Web3FunctionContext) => {
await storage.set("lastRun", timestamp.toString());

SimulationUrlBuilder.log(
[WITHDRAWER_ADDRESS],
[callData[0].to],
[0],
[callData[0].data],
[gelatoArgs.chainId],
callData.map(() => GELATO_PROXY),
callData.map(({ to }) => to),
callData.map(() => 0),
callData.map(({ data }) => data),
callData.map(() => gelatoArgs.chainId),
);

return {
Expand Down

0 comments on commit 09757e9

Please sign in to comment.