Skip to content

Commit

Permalink
Merge pull request #4 from nation3/JMF-adding-venation-balance-check
Browse files Browse the repository at this point in the history
Updated to read the balance of veNation for the Passport Holder and filter when less than 1.5
  • Loading branch information
johnmark13 authored Nov 25, 2023
2 parents 98f89d7 + db94b49 commit 2e3f996
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

Calculates voting power using a cooperative model (one person one vote) based on a user's ownership of nation3 passport (_erc721 NFT_). It also takes into account whether the NFT owner delegated his voting power to another account (using the `setSigner` function)

## Requires 1 input parameters:
## Requires 2 input parameters:

**erc20**

The address of veNation tokens contract

**erc721**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@
"strategy": {
"name": "nation3-passport-coop-with-delegations",
"params": {
"erc721": "0x3337dac9f251d4e403d6030e18e3cfb6a2cb1333"
"erc721": "0x3337dac9f251d4e403d6030e18e3cfb6a2cb1333",
"erc20": "0xf7def1d2fbda6b74bee7452fdf7894da9201065d"
}
},
"network": "1",
"addresses": [
"0x61c872A66d79d932F9aEE874b397F2D50Ed78326",
"0xEdd000B7Db3cb8931d4E0cb1D0DBe6B947Ceb09A",
"0x47d80912400ef8f8224531EBEB1ce8f2ACf4b75a",
"0x636d65212C815b93B8E5b069f7082169cec851b7",
"0x460AF11e497dc273fC163414943C6fd95d17B1fd",
"0xfafda3727fe0406e50230bf6092be5ded68cd9e9",
"0x79438224Bc21b0E6B45ECF9F8caADfBdB874DedD"
],
"snapshot": 17683972
"snapshot": 18611783
}
]
59 changes: 51 additions & 8 deletions src/strategies/nation3-passport-coop-with-delegations/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { BigNumber } from '@ethersproject/bignumber';
import { BigNumber, BigNumberish } from '@ethersproject/bignumber';
import { Multicaller } from '../../utils';
import { formatUnits } from '@ethersproject/units';

export const author = 'nation3';
export const version = '0.2.0';

const DECIMALS = 18;

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

const ownerAbi = ['function ownerOf(uint256 id) public view returns (address)'];

const signerAbi = [
'function signerOf(uint256 id) external view returns (address)'
];
Expand All @@ -23,6 +32,12 @@ export async function strategy(
const erc721SignerCaller = new Multicaller(network, provider, signerAbi, {
blockTag
});
const erc721OwnerCaller = new Multicaller(network, provider, ownerAbi, {
blockTag
});
const erc20BalanceCaller = new Multicaller(network, provider, balanceAbi, {
blockTag
});
const erc721LastTokenIdCaller = new Multicaller(
network,
provider,
Expand All @@ -35,18 +50,46 @@ export async function strategy(
const lastIndex = await erc721LastTokenIdCaller.execute();
const lastTokenId = BigNumber.from(lastIndex.lastTokenId).toNumber();

for (let i = 0; i < lastTokenId; i++) {
for (let i = 1; i < lastTokenId; i++) {
erc721SignerCaller.call(i, options.erc721, 'signerOf', [i]);
erc721OwnerCaller.call(i, options.erc721, 'ownerOf', [i]);
}

const erc721Signers: Record<string, string> =
await erc721SignerCaller.execute();
const [erc721Signers, erc721Owners]: [
Record<string, string>,
Record<string, string>
] = await Promise.all([
erc721SignerCaller.execute(),
erc721OwnerCaller.execute()
]);

const erc721SignersArr = Object.entries(erc721Signers);
const erc721OwnersArr = Object.entries(erc721Owners);

const eligibleAddresses = erc721SignersArr
.map(([, address]) => address)
.filter((address) => addresses.includes(address));
const eligibleAddresses = erc721SignersArr.filter(([, address]) =>
addresses.includes(address)
);

//create a combined tuple
const eligibleSignerOwner: [string, string, string][] = eligibleAddresses.map(
([id, signerAddress]) => {
const owner = erc721OwnersArr.find(([ownerId]) => id === ownerId);
return [id, signerAddress, owner ? owner[1] : '0x0'];
}
);

eligibleSignerOwner.forEach(([, , owner]) =>
erc20BalanceCaller.call(owner, options.erc20, 'balanceOf', [owner])
);

const erc20Balances: Record<string, BigNumberish> =
await erc20BalanceCaller.execute();

//now we have balances, need to check for > 1.5 on all IDs that have voted
const withPower = eligibleSignerOwner.filter(([, , owner]) => {
const balance = erc20Balances[owner] || 0;
return parseFloat(formatUnits(balance, DECIMALS)) > 1.5;
});

return Object.fromEntries(eligibleAddresses.map((value) => [value, 1]));
return Object.fromEntries(withPower.map(([, signer]) => [signer, 1])) || [];
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
"title": "Strategy",
"type": "object",
"properties": {
"erc20": {
"type": "string",
"title": "veNation",
"examples": ["e.g. 0xf7def1d2fbda6b74bee7452fdf7894da9201065d"],
"pattern": "^0x[a-fA-F0-9]{40}$",
"minLength": 42,
"maxLength": 42
},
"erc721": {
"type": "string",
"title": "nation3 passport",
Expand All @@ -15,7 +23,7 @@
"maxLength": 42
}
},
"required": ["erc721"],
"required": ["erc20", "erc721"],
"additionalProperties": false
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/strategies/nation3-votes-with-delegations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export async function strategy(
const lastIndex = await erc721LastTokenIdCaller.execute();
const lastTokenId = BigNumber.from(lastIndex.lastTokenId).toNumber();

for (let i = 0; i < lastTokenId; i++) {
for (let i = 1; i < lastTokenId; i++) {
erc721SignerCaller.call(i, options.erc721, 'signerOf', [i]);
erc721OwnerCaller.call(i, options.erc721, 'ownerOf', [i]);
}
Expand Down

0 comments on commit 2e3f996

Please sign in to comment.