From 01022a66a9ceca01b9e770514b6410e9fd144873 Mon Sep 17 00:00:00 2001 From: sunrisedao <87509707+sunrisedao@users.noreply.github.com> Date: Fri, 17 Sep 2021 12:00:26 +0700 Subject: [PATCH] add add sunrisegaming-univ2-lp strategy (#65) --- src/strategies/index.ts | 2 + .../sunrisegaming-univ2-lp/README.md | 16 ++++ .../sunrisegaming-univ2-lp/examples.json | 27 ++++++ .../sunrisegaming-univ2-lp/index.ts | 82 +++++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 src/strategies/sunrisegaming-univ2-lp/README.md create mode 100644 src/strategies/sunrisegaming-univ2-lp/examples.json create mode 100644 src/strategies/sunrisegaming-univ2-lp/index.ts diff --git a/src/strategies/index.ts b/src/strategies/index.ts index 89a689ff3..b347fa07d 100644 --- a/src/strategies/index.ts +++ b/src/strategies/index.ts @@ -143,6 +143,7 @@ import * as snowswap from './snowswap'; import * as meebitsdao from './meebitsdao'; import * as crucibleERC20BalanceOf from './crucible-erc20-balance-of'; import * as hasrock from './has-rock'; +import * as sunriseGamingUniv2Lp from './sunrisegaming-univ2-lp'; import * as sunriseGamingStaking from './sunrisegaming-staking'; const strategies = { @@ -288,6 +289,7 @@ const strategies = { snowswap, meebitsdao, 'crucible-erc20-balance-of': crucibleERC20BalanceOf, + 'sunrisegaming-univ2-lp': sunriseGamingUniv2Lp, 'sunrisegaming-staking': sunriseGamingStaking, 'has-rock': hasrock }; diff --git a/src/strategies/sunrisegaming-univ2-lp/README.md b/src/strategies/sunrisegaming-univ2-lp/README.md new file mode 100644 index 000000000..b79cd426e --- /dev/null +++ b/src/strategies/sunrisegaming-univ2-lp/README.md @@ -0,0 +1,16 @@ +# Sunrise Gaming Uniswap LP + +This strategy returns balances of the underlying token in Sunrise LP pools + +Here is an example of parameters: + +```json +{ + "symbol": "SUNC", + "decimals": 18, + "tokenAddress": "0x692accdd8b86692427e0aa4752ae917df01cc56f", + "lpTokenAddress": "0xaf5a7469Cf2571b973AEee9AE2f8aad00e1337d2", + "stakingAddress": "0x7dbE40ac6bB41A5FE4Fa2C74f31d7DEFBC793B58", + "poolIndex": 1 +} +``` \ No newline at end of file diff --git a/src/strategies/sunrisegaming-univ2-lp/examples.json b/src/strategies/sunrisegaming-univ2-lp/examples.json new file mode 100644 index 000000000..7364f6205 --- /dev/null +++ b/src/strategies/sunrisegaming-univ2-lp/examples.json @@ -0,0 +1,27 @@ +[ + { + "name": "Staked Univ2 LP for token", + "strategy": { + "name": "sunrisegaming-univ2-lp", + "params": { + "symbol": "SUNC", + "decimals": 18, + "tokenAddress": "0x692accdd8b86692427e0aa4752ae917df01cc56f", + "lpTokenAddress": "0xaf5a7469Cf2571b973AEee9AE2f8aad00e1337d2", + "stakingAddress": "0x7dbE40ac6bB41A5FE4Fa2C74f31d7DEFBC793B58", + "poolIndex": 1 + } + }, + "network": "1", + "addresses": [ + "0x7dbe40ac6bb41a5fe4fa2c74f31d7defbc793b58", + "0x26533020822f9b28c801e6beb772ef74dfe0c81e", + "0x75bd5989ce8f962a1864d8a0af8bfb5130805722", + "0x7505afcd576bb995577a944bccdb5c54c7d5ec45", + "0x930af93baa5f2c2f71bafd5a2fd7b1d47a61c352", + "0xbc444050d78107872c0262452fff004da9208258", + "0x26533020822f9b28c801e6beb772ef74dfe0c81e" + ], + "snapshot": 13227497 + } +] \ No newline at end of file diff --git a/src/strategies/sunrisegaming-univ2-lp/index.ts b/src/strategies/sunrisegaming-univ2-lp/index.ts new file mode 100644 index 000000000..63f05b133 --- /dev/null +++ b/src/strategies/sunrisegaming-univ2-lp/index.ts @@ -0,0 +1,82 @@ +import { multicall } from '../../utils'; +import { formatUnits } from '@ethersproject/units'; +import { BigNumber } from '@ethersproject/bignumber'; + +export const author = 'sunrisedao'; +export const version = '0.1.0'; + +const erc20Abi = [ + 'function totalSupply() view returns (uint256)', + 'function balanceOf(address account) view returns (uint256)' +]; + +const masterChefAbi = [ + 'function userInfo(uint256, address) view returns (uint256 amount, uint256 rewardDebt)' +]; + +function bn(num: any): BigNumber { + return BigNumber.from(num.toString()); +} + +export async function strategy( + _space, + network, + provider, + addresses, + options, + snapshot +) { + const blockTag = typeof snapshot === 'number' ? snapshot : 'latest'; + + // Get LP balances + let res = await multicall( + network, + provider, + erc20Abi, + [ + [options.lpTokenAddress, 'totalSupply', []], + [options.tokenAddress, 'balanceOf', [options.lpTokenAddress]], + ...addresses.map((address: any) => [ + options.lpTokenAddress, + 'balanceOf', + [address] + ]) + ], + { blockTag } + ); + + const lpTokenTotalSupply = bn(res[0]); // decimal: 18 + const totalTokensInPool = bn(res[1]); // decimal: options.decimal + + res = res.slice(2); + + // Get staked LP in staking constract + let stakedRes = await multicall( + network, + provider, + masterChefAbi, + [ + ...addresses.map((address: any) => [ + options.stakingAddress, + 'userInfo', + [options.poolIndex, address] + ]) + ], + { blockTag } + ); + + // How much tokens user has from LP tokens + const usersTokensFromLp = res.slice(0, addresses.length).map((amount, i) => { + const totalLp = bn(amount).add(bn(stakedRes[i].amount)); // decimal: 18 + + // (LP + StakedLP) x token.balanceOf(LPToken) / LPToken.totalSupply() + return totalLp.mul(totalTokensInPool).div(lpTokenTotalSupply); // decimal: options.decimal + }); + + return Object.fromEntries( + usersTokensFromLp.map((sum, i) => { + const parsedSum = parseFloat(formatUnits(sum, options.decimal)); + return [addresses[i], parsedSum]; + }) + ); +}