Skip to content

Commit

Permalink
Merge branch 'master' into eco/multichain-voting-power
Browse files Browse the repository at this point in the history
  • Loading branch information
ChaituVR authored Jan 22, 2025
2 parents c800e80 + 9e4e036 commit 053de55
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 1 deletion.
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 morphoDelegation from './morpho-delegation';
import * as lizcoinStrategy2024 from './lizcoin-strategy-2024';
import * as realt from './realt';
import * as superfluidVesting from './superfluid-vesting';
import * as synapse from './synapse';

const strategies = {
'delegatexyz-erc721-balance-of': delegatexyzErc721BalanceOf,
Expand Down Expand Up @@ -952,7 +953,8 @@ const strategies = {
'morpho-delegation': morphoDelegation,
'lizcoin-strategy-2024': lizcoinStrategy2024,
realt,
'superfluid-vesting': superfluidVesting
'superfluid-vesting': superfluidVesting,
synapse
};

Object.keys(strategies).forEach(function (strategyName) {
Expand Down
64 changes: 64 additions & 0 deletions src/strategies/synapse/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Synapse Strategy

This strategy calculates voting power by combining two components:
1. SYN token balance
2. Locked SYN tokens in the staking contract

## Overview

The strategy sums up:
- The regular SYN token balance (`balanceOf`)
- The locked amount in the staking contract (`lockedAmountOf`)

## Parameters

Here is an example of parameters:

```json
{
"symbol": "SYN",
"tokenAddress": "0x0f2D719407FdBeFF09D87557AbB7232601FD9F29",
"stakingAddress": "0x00000010cd90b3688d249d84c616de3a0343e60f",
"decimals": 18
}
```

### Parameter Details

- `symbol`: Token symbol (default: "SYN")
- `tokenAddress`: The SYN token contract address for the specific network
- `stakingAddress`: The staking contract address (default: 0x00000010cd90b3688d249d84c616de3a0343e60f)
- `decimals`: Token decimals (default: 18)

## Networks & Addresses

The strategy works across multiple networks. Here are the SYN token addresses for each supported chain:

- Ethereum: `0x0f2D719407FdBeFF09D87557AbB7232601FD9F29`
- Arbitrum: `0x080f6aed32fc474dd5717105dba5ea57268f46eb`
- Aurora: `0xd80d8688b02B3FD3afb81cDb124F188BB5aD0445`
- Avalanche: `0x1f1E7c893855525b303f99bDF5c3c05Be09ca251`
- Base: `0x432036208d2717394d2614d6697c46DF3Ed69540`
- Blast: `0x9592f08387134e218327E6E8423400eb845EdE0E`
- Boba: `0xb554A55358fF0382Fb21F0a478C3546d1106Be8c`
- BSC: `0xa4080f1778e69467e905b8d6f72f6e441f9e9484`
- Canto: `0x555982d2E211745b96736665e19D9308B615F78e`
- Cronos: `0xFD0F80899983b8D46152aa1717D76cba71a31616`
- DFK Chain: `0xB6b5C854a8f71939556d4f3a2e5829F7FcC1bf2A`
- Fantom: `0xE55e19Fb4F2D85af758950957714292DAC1e25B2`
- Harmony: `0xE55e19Fb4F2D85af758950957714292DAC1e25B2`
- Metis: `0x67c10c397dd0ba417329543c1a40eb48aaa7cd00`
- Moonbeam: `0xF44938b0125A6662f9536281aD2CD6c499F22004`
- Moonriver: `0xd80d8688b02B3FD3afb81cDb124F188BB5aD0445`
- Optimism: `0x5A5fFf6F753d7C11A56A52FE47a177a87e431655`
- Polygon: `0xf8f9efc0db77d8881500bb06ff5d6abc3070e695`

Note: Staking functionality is only available on Ethereum, Arbitrum, Avalanche, Optimism, BSC, Polygon, and Base networks.

## Example

If a user has:
- 100 SYN tokens in their wallet
- 50 SYN tokens locked in staking

Their total voting power would be 150 SYN tokens.
19 changes: 19 additions & 0 deletions src/strategies/synapse/examples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"name": "Example Query",
"strategy": {
"name": "synapse",
"params": {
"symbol": "SYN",
"decimals": 18
}
},
"network": "1",
"addresses": [
"0xBdfbc9f2A873E07599CafA9BC18F80D4e07D7832",
"0x20D84F5e6533b48cdC8E557eD50d7825eBA77766",
"0xb73AcB429Ba868984c0236bdf940D4FE1E643F27"
],
"snapshot": 21622022
}
]
164 changes: 164 additions & 0 deletions src/strategies/synapse/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { formatUnits } from '@ethersproject/units';
import { BigNumber } from '@ethersproject/bignumber';
import { getAddress } from '@ethersproject/address';
import { Multicaller } from '../../utils';

export const author = 'defi-moses';
export const version = '0.2.0';

const SUPPORTED_CHAINS = {
'1': {
tokenAddress: '0x0f2D719407FdBeFF09D87557AbB7232601FD9F29',
stakingAddress: '0x00000010cd90b3688d249d84c616de3a0343e60f'
},
'42161': {
// Arbitrum
tokenAddress: '0x080f6aed32fc474dd5717105dba5ea57268f46eb',
stakingAddress: '0x00000010cd90b3688d249d84c616de3a0343e60f'
},
'43114': {
// Avalanche
tokenAddress: '0x1f1E7c893855525b303f99bDF5c3c05Be09ca251',
stakingAddress: '0x00000010cd90b3688d249d84c616de3a0343e60f'
},
'10': {
// Optimism
tokenAddress: '0x5A5fFf6F753d7C11A56A52FE47a177a87e431655',
stakingAddress: '0x00000010cd90b3688d249d84c616de3a0343e60f'
},
'56': {
// BSC
tokenAddress: '0xa4080f1778e69467e905b8d6f72f6e441f9e9484',
stakingAddress: '0x00000010cd90b3688d249d84c616de3a0343e60f'
},
'137': {
// Polygon
tokenAddress: '0xf8f9efc0db77d8881500bb06ff5d6abc3070e695',
stakingAddress: '0x00000010cd90b3688d249d84c616de3a0343e60f'
},
'8453': {
// Base
tokenAddress: '0x432036208d2717394d2614d6697c46DF3Ed69540',
stakingAddress: '0x00000010cd90b3688d249d84c616de3a0343e60f'
}
};

const tokenAbi = [
'function balanceOf(address) view returns (uint256)',
'function decimals() view returns (uint8)'
];

const stakingAbi = [
'function lockedAmountOf(address account) view returns (uint256)',
'function balanceOf(address account) view returns (uint256)' // Backup method
];

interface MulticallResult {
[key: string]: {
[address: string]: BigNumber;
};
}

async function getChainBalance(
network: string,
provider,
addresses: string[],
options,
snapshot
): Promise<Record<string, number>> {
const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';
const chainConfig = SUPPORTED_CHAINS[network];
if (!chainConfig) {
throw new Error(`Network ${network} not supported`);
}

try {
const multi = new Multicaller(network, provider, tokenAbi, { blockTag });
const checksumAddresses = addresses.map(getAddress);

checksumAddresses.forEach((address) => {
multi.call(`token.${address}`, chainConfig.tokenAddress, 'balanceOf', [
address
]);
});

const result = (await multi.execute()) as MulticallResult;
const stakingMulti = new Multicaller(network, provider, stakingAbi, {
blockTag
});
let stakingResult: MulticallResult = { staking: {} };

try {
checksumAddresses.forEach((address) => {
stakingMulti.call(
`staking.${address}`,
chainConfig.stakingAddress,
'lockedAmountOf',
[address]
);
});
stakingResult = await stakingMulti.execute();
} catch (error) {
const balanceMulti = new Multicaller(network, provider, stakingAbi, {
blockTag
});
checksumAddresses.forEach((address) => {
balanceMulti.call(
`staking.${address}`,
chainConfig.stakingAddress,
'balanceOf',
[address]
);
});

try {
stakingResult = await balanceMulti.execute();
} catch (error) {
console.warn(`Failed to fetch staking balances for network ${network}`);
}
}

return Object.fromEntries(
checksumAddresses.map((address) => {
const tokenBalance = result.token?.[address] || BigNumber.from(0);
const stakedBalance =
stakingResult.staking?.[address] || BigNumber.from(0);

const formattedTokenBalance = parseFloat(
formatUnits(tokenBalance, options.decimals)
);
const formattedStakedBalance = parseFloat(
formatUnits(stakedBalance, options.decimals)
);

return [address, formattedTokenBalance + formattedStakedBalance];
})
);
} catch (error) {
throw new Error(`Error fetching balances for network ${network}: ${error}`);
}
}

export async function strategy(
space,
network,
provider,
addresses,
options,
snapshot
): Promise<Record<string, number>> {
// Check if the selected network is supported
if (!SUPPORTED_CHAINS[network]) {
throw new Error(`Network ${network} not supported`);
}

const result = await getChainBalance(
network,
provider,
addresses,
options,
snapshot
);

return result;
}
23 changes: 23 additions & 0 deletions src/strategies/synapse/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Strategy",
"definitions": {
"Strategy": {
"title": "Strategy",
"type": "object",
"properties": {
"symbol": {
"type": ["string", "null"],
"title": "Symbol",
"default": "SYN"
},
"decimals": {
"type": "number",
"title": "Decimals",
"default": 18
}
},
"required": ["decimals"]
}
}
}

0 comments on commit 053de55

Please sign in to comment.