Skip to content

Commit

Permalink
[floki] add floki strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
AlissonRS committed Oct 30, 2023
1 parent 9e9e71e commit 13ab6f5
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 1 deletion.
14 changes: 14 additions & 0 deletions src/strategies/floki/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# FLOKI

This is the strategy used by FLOKI DAO. It returns the FLOKI balance, as well as staked amount with pool's multiplier taken into account (which depends on how long the tokens were staked for).

Here is an example of parameters:

```json
{
"tokenAddress": "0xcf0C122c6b73ff809C693DB761e7BaeBe62b6a2E",
"stakingPoolAddress": "0xb8D2471E35eE033Db509e0456c8eFc4135f4EE43",
"stakingPoolMultiplierAddress": "0xB254CC6c1D178C2dE8182CEDE6113A986bB90721",
"decimals": 9
}
```
22 changes: 22 additions & 0 deletions src/strategies/floki/examples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"name": "Example query",
"strategy": {
"name": "floki",
"params": {
"tokenAddress": "0xcf0C122c6b73ff809C693DB761e7BaeBe62b6a2E",
"stakingPoolAddress": "0xb8D2471E35eE033Db509e0456c8eFc4135f4EE43",
"stakingPoolMultiplierAddress": "0xB254CC6c1D178C2dE8182CEDE6113A986bB90721",
"decimals": 9
}
},
"network": "1",
"addresses": [
"0x78C4f5CEF16333804394fE736fC5868351968Fd7",
"0x2cc848EA4C5313Fe5a264D12c7c2181f14f0A5E7",
"0x5BA9e392Baf5D082d968E1BFA945F99e54BF8123",
"0x308DA792A0b9c332D5254bB2afB78640d363e2d1"
],
"snapshot": 18458827
}
]
80 changes: 80 additions & 0 deletions src/strategies/floki/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { BigNumber, BigNumberish } from '@ethersproject/bignumber';
import { formatUnits } from '@ethersproject/units';
import { Multicaller } from '../../utils';

export const author = 'AlissonRS';
export const version = '0.0.1';

const tokenAbi = [
'function balanceOf(address account) external view returns (uint256)'
];

const poolAbi = [
'function getUserStakes(address _user) external view returns (tuple(uint256 stakedAmount, uint256 minimumStakeTimestamp, uint256 duration, uint256 rewardPerTokenPaid, uint256 rewards)[])'
];

const multiplierAbi = [
'function applyMultiplier(uint256 _amount, uint256 _duration) external view returns (uint256)'
];

export async function strategy(
space,
network,
provider,
addresses,
options,
snapshot
): Promise<Record<string, number>> {
const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';

const balanceMulti = new Multicaller(network, provider, tokenAbi, {
blockTag
});
addresses.forEach((address) =>
balanceMulti.call(address, options.tokenAddress, 'balanceOf', [address])
);
const balanceResult: Record<string, BigNumberish> =
await balanceMulti.execute();

// Find the staked tokens
const stakingMulti = new Multicaller(network, provider, poolAbi, {
blockTag
});
addresses.forEach((address) =>
stakingMulti.call(address, options.stakingPoolAddress, 'getUserStakes', [
address
])
);
const stakingResult: Record<string, any> = await stakingMulti.execute();

// Get the multiplier factor for each wallet
const multiplierMulti = new Multicaller(network, provider, multiplierAbi, {
blockTag
});
Object.entries(stakingResult).forEach(([address, stakesInfo]) => {
stakesInfo.forEach((stakeInfo, i) =>
multiplierMulti.call(
`${address}-${i}`,
options.stakingPoolMultiplierAddress,
'applyMultiplier',
[stakeInfo.stakedAmount, stakeInfo.duration]
)
);
});
const multiResult: Record<string, any> = await multiplierMulti.execute();

// Add staking tokens to the balance
Object.entries(multiResult).forEach(([addressPos, stakeBalance]) => {
const address = addressPos.substring(0, 42);
balanceResult[address] = BigNumber.from(balanceResult[address]).add(
stakeBalance
);
});

return Object.fromEntries(
Object.entries(balanceResult).map(([address, balance]) => [
address,
parseFloat(formatUnits(balance, options.decimals))
])
);
}
49 changes: 49 additions & 0 deletions src/strategies/floki/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Strategy",
"definitions": {
"Strategy": {
"title": "Strategy",
"type": "object",
"properties": {
"symbol": {
"type": "string",
"title": "Symbol",
"examples": ["e.g. FLOKI"],
"maxLength": 16
},
"tokenAddress": {
"type": "string",
"title": "Token address",
"examples": ["e.g. 0xcf0C122c6b73ff809C693DB761e7BaeBe62b6a2E"],
"pattern": "^0x[a-fA-F0-9]{40}$",
"minLength": 42,
"maxLength": 42
},
"stakingPoolAddress": {
"type": "string",
"title": "Staking Pool address",
"examples": ["e.g. 0xb8D2471E35eE033Db509e0456c8eFc4135f4EE43"],
"pattern": "^0x[a-fA-F0-9]{40}$",
"minLength": 42,
"maxLength": 42
},
"stakingPoolMultiplierAddress": {
"type": "string",
"title": "Staking Pool Multiplier address",
"examples": ["e.g. 0xB254CC6c1D178C2dE8182CEDE6113A986bB90721"],
"pattern": "^0x[a-fA-F0-9]{40}$",
"minLength": 42,
"maxLength": 42
},
"decimals": {
"type": "number",
"title": "Decimals",
"examples": ["e.g. 9"]
}
},
"required": ["tokenAddress", "stakingPoolAddress", "stakingPoolMultiplierAddress", "decimals"],
"additionalProperties": false
}
}
}
4 changes: 3 additions & 1 deletion src/strategies/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ import * as eoaBalanceAndStakingPools from './eoa-balance-and-staking-pools';
import * as stationScoreIfBadge from './station-score-if-badge';
import * as stationConstantIfBadge from './station-constant-if-badge';
import * as mangroveStationQVScaledToMGV from './mangrove-station-qv-scaled-to-mgv';
import * as floki from './floki';

const strategies = {
'cap-voting-power': capVotingPower,
Expand Down Expand Up @@ -950,7 +951,8 @@ const strategies = {
'eoa-balance-and-staking-pools': eoaBalanceAndStakingPools,
'station-score-if-badge': stationScoreIfBadge,
'station-constant-if-badge': stationConstantIfBadge,
'mangrove-station-qv-scaled-to-mgv': mangroveStationQVScaledToMGV
'mangrove-station-qv-scaled-to-mgv': mangroveStationQVScaledToMGV,
floki
};

Object.keys(strategies).forEach(function (strategyName) {
Expand Down

0 comments on commit 13ab6f5

Please sign in to comment.