Skip to content
This repository was archived by the owner on Jan 24, 2024. It is now read-only.

Commit 506a38d

Browse files
author
William Poulin
authored
feat(abracadabra): Add MIM-2Crv STIP boosted position (#3156)
1 parent a5148ad commit 506a38d

6 files changed

Lines changed: 1060 additions & 0 deletions

File tree

src/apps/abracadabra/abracadabra.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Module } from '@nestjs/common';
33
import { AbstractApp } from '~app/app.dynamic-module';
44

55
import { ArbitrumAbracadabraCauldronContractPositionFetcher } from './arbitrum/abracadabra.cauldron.contract-position-fetcher';
6+
import { ArbitrumAbracadabraFarmBoostedContractPositionFetcher } from './arbitrum/abracadabra.farm-boosted.contract-position-fetcher';
67
import { ArbitrumAbracadabraFarmContractPositionFetcher } from './arbitrum/abracadabra.farm.contract-position-fetcher';
78
import { ArbitrumAbracadabraMspellContractPositionFetcher } from './arbitrum/abracadabra.m-spell.contract-position-fetcher';
89
import { ArbitrumAbracadabraMagicGlpTokenFetcher } from './arbitrum/abracadabra.magic-glp.token-fetcher';
@@ -35,6 +36,7 @@ import { OptimismAbracadabraErc20VaultsTokenFetcher } from './optimism/abracadab
3536
ArbitrumAbracadabraMagicGlpTokenFetcher,
3637
ArbitrumAbracadabraMspellContractPositionFetcher,
3738
ArbitrumAbracadabraStakedSpellTokenFetcher,
39+
ArbitrumAbracadabraFarmBoostedContractPositionFetcher,
3840
// Avalanche
3941
AvalancheAbracadabraCauldronContractPositionFetcher,
4042
AvalancheAbracadabraFarmContractPositionFetcher,
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { Inject } from '@nestjs/common';
2+
import { compact, range } from 'lodash';
3+
4+
import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface';
5+
import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator';
6+
import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present';
7+
import { isViemMulticallUnderlyingError } from '~multicall/errors';
8+
import { MetaType } from '~position/position.interface';
9+
import { isClaimable } from '~position/position.utils';
10+
import { ContractPositionTemplatePositionFetcher } from '~position/template/contract-position.template.position-fetcher';
11+
import {
12+
GetDisplayPropsParams,
13+
GetTokenBalancesParams,
14+
GetTokenDefinitionsParams,
15+
} from '~position/template/contract-position.template.types';
16+
17+
import { AbracadabraViemContractFactory } from '../contracts';
18+
import { AbracadabraFarmBoosted } from '../contracts/viem';
19+
20+
@PositionTemplate()
21+
export class ArbitrumAbracadabraFarmBoostedContractPositionFetcher extends ContractPositionTemplatePositionFetcher<AbracadabraFarmBoosted> {
22+
groupLabel = 'Staking';
23+
24+
constructor(
25+
@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit,
26+
@Inject(AbracadabraViemContractFactory) protected readonly contractFactory: AbracadabraViemContractFactory,
27+
) {
28+
super(appToolkit);
29+
}
30+
31+
getContract(address: string) {
32+
return this.contractFactory.abracadabraFarmBoosted({ address, network: this.network });
33+
}
34+
35+
async getDefinitions() {
36+
return [{ address: '0x6d2070b13929df15b13d96cfc509c574168988cd' }];
37+
}
38+
39+
async getTokenDefinitions({ contract }: GetTokenDefinitionsParams<AbracadabraFarmBoosted>) {
40+
const rewardTokenAddressesRaw = await Promise.all(
41+
range(0, 2).map(i => {
42+
return contract.read.rewardTokens([BigInt(i)]).catch(err => {
43+
if (isViemMulticallUnderlyingError(err)) return null;
44+
});
45+
}),
46+
);
47+
const rewardTokenAddresses = compact(rewardTokenAddressesRaw);
48+
return [
49+
{
50+
metaType: MetaType.SUPPLIED,
51+
address: await contract.read.stakingToken(),
52+
network: this.network,
53+
},
54+
...rewardTokenAddresses.map(address => ({
55+
metaType: MetaType.CLAIMABLE,
56+
address,
57+
network: this.network,
58+
})),
59+
];
60+
}
61+
62+
async getLabel({ contractPosition }: GetDisplayPropsParams<AbracadabraFarmBoosted>) {
63+
return getLabelFromToken(contractPosition.tokens[0]);
64+
}
65+
66+
async getTokenBalancesPerPosition({
67+
address,
68+
contract,
69+
contractPosition,
70+
}: GetTokenBalancesParams<AbracadabraFarmBoosted>) {
71+
const rewardTokens = contractPosition.tokens.filter(isClaimable);
72+
const claimables = await Promise.all(rewardTokens.map(v => contract.read.earned([address, v.address])));
73+
74+
const supplied = await contract.read.balanceOf([address]);
75+
76+
return [supplied, ...claimables];
77+
}
78+
}
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
[
2+
{
3+
"inputs": [
4+
{ "internalType": "address", "name": "_stakingToken", "type": "address" },
5+
{ "internalType": "address", "name": "_owner", "type": "address" }
6+
],
7+
"stateMutability": "nonpayable",
8+
"type": "constructor"
9+
},
10+
{ "inputs": [], "name": "ErrInvalidTokenAddress", "type": "error" },
11+
{ "inputs": [], "name": "ErrRewardAlreadyAdded", "type": "error" },
12+
{ "inputs": [], "name": "ErrRewardPeriodStillActive", "type": "error" },
13+
{ "inputs": [], "name": "ErrZeroAmount", "type": "error" },
14+
{ "inputs": [], "name": "ErrZeroDuration", "type": "error" },
15+
{ "inputs": [], "name": "NotAllowedOperator", "type": "error" },
16+
{
17+
"anonymous": false,
18+
"inputs": [
19+
{ "indexed": false, "internalType": "address", "name": "token", "type": "address" },
20+
{ "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }
21+
],
22+
"name": "LogRecovered",
23+
"type": "event"
24+
},
25+
{
26+
"anonymous": false,
27+
"inputs": [{ "indexed": false, "internalType": "uint256", "name": "reward", "type": "uint256" }],
28+
"name": "LogRewardAdded",
29+
"type": "event"
30+
},
31+
{
32+
"anonymous": false,
33+
"inputs": [
34+
{ "indexed": true, "internalType": "address", "name": "user", "type": "address" },
35+
{ "indexed": true, "internalType": "address", "name": "rewardsToken", "type": "address" },
36+
{ "indexed": false, "internalType": "uint256", "name": "reward", "type": "uint256" }
37+
],
38+
"name": "LogRewardPaid",
39+
"type": "event"
40+
},
41+
{
42+
"anonymous": false,
43+
"inputs": [
44+
{ "indexed": false, "internalType": "address", "name": "token", "type": "address" },
45+
{ "indexed": false, "internalType": "uint256", "name": "newDuration", "type": "uint256" }
46+
],
47+
"name": "LogRewardsDurationUpdated",
48+
"type": "event"
49+
},
50+
{
51+
"anonymous": false,
52+
"inputs": [
53+
{ "indexed": true, "internalType": "address", "name": "user", "type": "address" },
54+
{ "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }
55+
],
56+
"name": "LogStaked",
57+
"type": "event"
58+
},
59+
{
60+
"anonymous": false,
61+
"inputs": [
62+
{ "indexed": true, "internalType": "address", "name": "user", "type": "address" },
63+
{ "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }
64+
],
65+
"name": "LogWithdrawn",
66+
"type": "event"
67+
},
68+
{
69+
"anonymous": false,
70+
"inputs": [
71+
{ "indexed": true, "internalType": "address", "name": "", "type": "address" },
72+
{ "indexed": false, "internalType": "bool", "name": "", "type": "bool" }
73+
],
74+
"name": "OperatorChanged",
75+
"type": "event"
76+
},
77+
{
78+
"anonymous": false,
79+
"inputs": [
80+
{ "indexed": true, "internalType": "address", "name": "user", "type": "address" },
81+
{ "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }
82+
],
83+
"name": "OwnershipTransferred",
84+
"type": "event"
85+
},
86+
{
87+
"anonymous": false,
88+
"inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }],
89+
"name": "Paused",
90+
"type": "event"
91+
},
92+
{
93+
"anonymous": false,
94+
"inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }],
95+
"name": "Unpaused",
96+
"type": "event"
97+
},
98+
{
99+
"inputs": [
100+
{ "internalType": "address", "name": "rewardToken", "type": "address" },
101+
{ "internalType": "uint256", "name": "_rewardsDuration", "type": "uint256" }
102+
],
103+
"name": "addReward",
104+
"outputs": [],
105+
"stateMutability": "nonpayable",
106+
"type": "function"
107+
},
108+
{
109+
"inputs": [{ "internalType": "address", "name": "user", "type": "address" }],
110+
"name": "balanceOf",
111+
"outputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }],
112+
"stateMutability": "view",
113+
"type": "function"
114+
},
115+
{
116+
"inputs": [
117+
{ "internalType": "address", "name": "user", "type": "address" },
118+
{ "internalType": "address", "name": "rewardToken", "type": "address" }
119+
],
120+
"name": "earned",
121+
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
122+
"stateMutability": "view",
123+
"type": "function"
124+
},
125+
{ "inputs": [], "name": "exit", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
126+
{
127+
"inputs": [{ "internalType": "address", "name": "rewardToken", "type": "address" }],
128+
"name": "getRewardForDuration",
129+
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
130+
"stateMutability": "view",
131+
"type": "function"
132+
},
133+
{ "inputs": [], "name": "getRewards", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
134+
{
135+
"inputs": [{ "internalType": "address", "name": "rewardToken", "type": "address" }],
136+
"name": "lastTimeRewardApplicable",
137+
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
138+
"stateMutability": "view",
139+
"type": "function"
140+
},
141+
{
142+
"inputs": [
143+
{ "internalType": "address", "name": "rewardToken", "type": "address" },
144+
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
145+
],
146+
"name": "notifyRewardAmount",
147+
"outputs": [],
148+
"stateMutability": "nonpayable",
149+
"type": "function"
150+
},
151+
{
152+
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
153+
"name": "operators",
154+
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
155+
"stateMutability": "view",
156+
"type": "function"
157+
},
158+
{
159+
"inputs": [],
160+
"name": "owner",
161+
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
162+
"stateMutability": "view",
163+
"type": "function"
164+
},
165+
{ "inputs": [], "name": "pause", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
166+
{
167+
"inputs": [],
168+
"name": "paused",
169+
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
170+
"stateMutability": "view",
171+
"type": "function"
172+
},
173+
{
174+
"inputs": [
175+
{ "internalType": "address", "name": "tokenAddress", "type": "address" },
176+
{ "internalType": "uint256", "name": "tokenAmount", "type": "uint256" }
177+
],
178+
"name": "recover",
179+
"outputs": [],
180+
"stateMutability": "nonpayable",
181+
"type": "function"
182+
},
183+
{
184+
"inputs": [{ "internalType": "address", "name": "token", "type": "address" }],
185+
"name": "rewardData",
186+
"outputs": [
187+
{
188+
"components": [
189+
{ "internalType": "uint256", "name": "rewardsDuration", "type": "uint256" },
190+
{ "internalType": "uint256", "name": "periodFinish", "type": "uint256" },
191+
{ "internalType": "uint256", "name": "rewardRate", "type": "uint256" },
192+
{ "internalType": "uint256", "name": "lastUpdateTime", "type": "uint256" },
193+
{ "internalType": "uint256", "name": "rewardPerTokenStored", "type": "uint256" }
194+
],
195+
"internalType": "struct MultiRewardsStaking.Reward",
196+
"name": "",
197+
"type": "tuple"
198+
}
199+
],
200+
"stateMutability": "view",
201+
"type": "function"
202+
},
203+
{
204+
"inputs": [{ "internalType": "address", "name": "rewardToken", "type": "address" }],
205+
"name": "rewardPerToken",
206+
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
207+
"stateMutability": "view",
208+
"type": "function"
209+
},
210+
{
211+
"inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
212+
"name": "rewardTokens",
213+
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
214+
"stateMutability": "view",
215+
"type": "function"
216+
},
217+
{
218+
"inputs": [
219+
{ "internalType": "address", "name": "user", "type": "address" },
220+
{ "internalType": "address", "name": "token", "type": "address" }
221+
],
222+
"name": "rewards",
223+
"outputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }],
224+
"stateMutability": "view",
225+
"type": "function"
226+
},
227+
{
228+
"inputs": [
229+
{ "internalType": "address", "name": "operator", "type": "address" },
230+
{ "internalType": "bool", "name": "status", "type": "bool" }
231+
],
232+
"name": "setOperator",
233+
"outputs": [],
234+
"stateMutability": "nonpayable",
235+
"type": "function"
236+
},
237+
{
238+
"inputs": [
239+
{ "internalType": "address", "name": "rewardToken", "type": "address" },
240+
{ "internalType": "uint256", "name": "_rewardsDuration", "type": "uint256" }
241+
],
242+
"name": "setRewardsDuration",
243+
"outputs": [],
244+
"stateMutability": "nonpayable",
245+
"type": "function"
246+
},
247+
{
248+
"inputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }],
249+
"name": "stake",
250+
"outputs": [],
251+
"stateMutability": "nonpayable",
252+
"type": "function"
253+
},
254+
{
255+
"inputs": [],
256+
"name": "stakingToken",
257+
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
258+
"stateMutability": "view",
259+
"type": "function"
260+
},
261+
{
262+
"inputs": [],
263+
"name": "totalSupply",
264+
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
265+
"stateMutability": "view",
266+
"type": "function"
267+
},
268+
{
269+
"inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }],
270+
"name": "transferOwnership",
271+
"outputs": [],
272+
"stateMutability": "nonpayable",
273+
"type": "function"
274+
},
275+
{ "inputs": [], "name": "unpause", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
276+
{
277+
"inputs": [
278+
{ "internalType": "address", "name": "user", "type": "address" },
279+
{ "internalType": "address", "name": "token", "type": "address" }
280+
],
281+
"name": "userRewardPerTokenPaid",
282+
"outputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }],
283+
"stateMutability": "view",
284+
"type": "function"
285+
},
286+
{
287+
"inputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }],
288+
"name": "withdraw",
289+
"outputs": [],
290+
"stateMutability": "nonpayable",
291+
"type": "function"
292+
}
293+
]

0 commit comments

Comments
 (0)