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

Commit

Permalink
feat(abracadabra): Add MIM-2Crv STIP boosted position (#3156)
Browse files Browse the repository at this point in the history
  • Loading branch information
wpoulin authored Dec 18, 2023
1 parent a5148ad commit 506a38d
Show file tree
Hide file tree
Showing 6 changed files with 1,060 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/apps/abracadabra/abracadabra.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Module } from '@nestjs/common';
import { AbstractApp } from '~app/app.dynamic-module';

import { ArbitrumAbracadabraCauldronContractPositionFetcher } from './arbitrum/abracadabra.cauldron.contract-position-fetcher';
import { ArbitrumAbracadabraFarmBoostedContractPositionFetcher } from './arbitrum/abracadabra.farm-boosted.contract-position-fetcher';
import { ArbitrumAbracadabraFarmContractPositionFetcher } from './arbitrum/abracadabra.farm.contract-position-fetcher';
import { ArbitrumAbracadabraMspellContractPositionFetcher } from './arbitrum/abracadabra.m-spell.contract-position-fetcher';
import { ArbitrumAbracadabraMagicGlpTokenFetcher } from './arbitrum/abracadabra.magic-glp.token-fetcher';
Expand Down Expand Up @@ -35,6 +36,7 @@ import { OptimismAbracadabraErc20VaultsTokenFetcher } from './optimism/abracadab
ArbitrumAbracadabraMagicGlpTokenFetcher,
ArbitrumAbracadabraMspellContractPositionFetcher,
ArbitrumAbracadabraStakedSpellTokenFetcher,
ArbitrumAbracadabraFarmBoostedContractPositionFetcher,
// Avalanche
AvalancheAbracadabraCauldronContractPositionFetcher,
AvalancheAbracadabraFarmContractPositionFetcher,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Inject } from '@nestjs/common';
import { compact, range } from 'lodash';

import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface';
import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator';
import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present';
import { isViemMulticallUnderlyingError } from '~multicall/errors';
import { MetaType } from '~position/position.interface';
import { isClaimable } from '~position/position.utils';
import { ContractPositionTemplatePositionFetcher } from '~position/template/contract-position.template.position-fetcher';
import {
GetDisplayPropsParams,
GetTokenBalancesParams,
GetTokenDefinitionsParams,
} from '~position/template/contract-position.template.types';

import { AbracadabraViemContractFactory } from '../contracts';
import { AbracadabraFarmBoosted } from '../contracts/viem';

@PositionTemplate()
export class ArbitrumAbracadabraFarmBoostedContractPositionFetcher extends ContractPositionTemplatePositionFetcher<AbracadabraFarmBoosted> {
groupLabel = 'Staking';

constructor(
@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit,
@Inject(AbracadabraViemContractFactory) protected readonly contractFactory: AbracadabraViemContractFactory,
) {
super(appToolkit);
}

getContract(address: string) {
return this.contractFactory.abracadabraFarmBoosted({ address, network: this.network });
}

async getDefinitions() {
return [{ address: '0x6d2070b13929df15b13d96cfc509c574168988cd' }];
}

async getTokenDefinitions({ contract }: GetTokenDefinitionsParams<AbracadabraFarmBoosted>) {
const rewardTokenAddressesRaw = await Promise.all(
range(0, 2).map(i => {
return contract.read.rewardTokens([BigInt(i)]).catch(err => {
if (isViemMulticallUnderlyingError(err)) return null;
});
}),
);
const rewardTokenAddresses = compact(rewardTokenAddressesRaw);
return [
{
metaType: MetaType.SUPPLIED,
address: await contract.read.stakingToken(),
network: this.network,
},
...rewardTokenAddresses.map(address => ({
metaType: MetaType.CLAIMABLE,
address,
network: this.network,
})),
];
}

async getLabel({ contractPosition }: GetDisplayPropsParams<AbracadabraFarmBoosted>) {
return getLabelFromToken(contractPosition.tokens[0]);
}

async getTokenBalancesPerPosition({
address,
contract,
contractPosition,
}: GetTokenBalancesParams<AbracadabraFarmBoosted>) {
const rewardTokens = contractPosition.tokens.filter(isClaimable);
const claimables = await Promise.all(rewardTokens.map(v => contract.read.earned([address, v.address])));

const supplied = await contract.read.balanceOf([address]);

return [supplied, ...claimables];
}
}
293 changes: 293 additions & 0 deletions src/apps/abracadabra/contracts/abis/abracadabra-farm-boosted.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
[
{
"inputs": [
{ "internalType": "address", "name": "_stakingToken", "type": "address" },
{ "internalType": "address", "name": "_owner", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "ErrInvalidTokenAddress", "type": "error" },
{ "inputs": [], "name": "ErrRewardAlreadyAdded", "type": "error" },
{ "inputs": [], "name": "ErrRewardPeriodStillActive", "type": "error" },
{ "inputs": [], "name": "ErrZeroAmount", "type": "error" },
{ "inputs": [], "name": "ErrZeroDuration", "type": "error" },
{ "inputs": [], "name": "NotAllowedOperator", "type": "error" },
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "address", "name": "token", "type": "address" },
{ "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "LogRecovered",
"type": "event"
},
{
"anonymous": false,
"inputs": [{ "indexed": false, "internalType": "uint256", "name": "reward", "type": "uint256" }],
"name": "LogRewardAdded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "user", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "rewardsToken", "type": "address" },
{ "indexed": false, "internalType": "uint256", "name": "reward", "type": "uint256" }
],
"name": "LogRewardPaid",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "address", "name": "token", "type": "address" },
{ "indexed": false, "internalType": "uint256", "name": "newDuration", "type": "uint256" }
],
"name": "LogRewardsDurationUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "user", "type": "address" },
{ "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "LogStaked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "user", "type": "address" },
{ "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "LogWithdrawn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "", "type": "address" },
{ "indexed": false, "internalType": "bool", "name": "", "type": "bool" }
],
"name": "OperatorChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "user", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }],
"name": "Paused",
"type": "event"
},
{
"anonymous": false,
"inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }],
"name": "Unpaused",
"type": "event"
},
{
"inputs": [
{ "internalType": "address", "name": "rewardToken", "type": "address" },
{ "internalType": "uint256", "name": "_rewardsDuration", "type": "uint256" }
],
"name": "addReward",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "user", "type": "address" }],
"name": "balanceOf",
"outputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "user", "type": "address" },
{ "internalType": "address", "name": "rewardToken", "type": "address" }
],
"name": "earned",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{ "inputs": [], "name": "exit", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
{
"inputs": [{ "internalType": "address", "name": "rewardToken", "type": "address" }],
"name": "getRewardForDuration",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{ "inputs": [], "name": "getRewards", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
{
"inputs": [{ "internalType": "address", "name": "rewardToken", "type": "address" }],
"name": "lastTimeRewardApplicable",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "rewardToken", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "notifyRewardAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
"name": "operators",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{ "inputs": [], "name": "pause", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
{
"inputs": [],
"name": "paused",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "tokenAddress", "type": "address" },
{ "internalType": "uint256", "name": "tokenAmount", "type": "uint256" }
],
"name": "recover",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "token", "type": "address" }],
"name": "rewardData",
"outputs": [
{
"components": [
{ "internalType": "uint256", "name": "rewardsDuration", "type": "uint256" },
{ "internalType": "uint256", "name": "periodFinish", "type": "uint256" },
{ "internalType": "uint256", "name": "rewardRate", "type": "uint256" },
{ "internalType": "uint256", "name": "lastUpdateTime", "type": "uint256" },
{ "internalType": "uint256", "name": "rewardPerTokenStored", "type": "uint256" }
],
"internalType": "struct MultiRewardsStaking.Reward",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "rewardToken", "type": "address" }],
"name": "rewardPerToken",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"name": "rewardTokens",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "user", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "rewards",
"outputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "bool", "name": "status", "type": "bool" }
],
"name": "setOperator",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "rewardToken", "type": "address" },
{ "internalType": "uint256", "name": "_rewardsDuration", "type": "uint256" }
],
"name": "setRewardsDuration",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }],
"name": "stake",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "stakingToken",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ "inputs": [], "name": "unpause", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
{
"inputs": [
{ "internalType": "address", "name": "user", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "userRewardPerTokenPaid",
"outputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }],
"name": "withdraw",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
Loading

0 comments on commit 506a38d

Please sign in to comment.