Skip to content

Commit

Permalink
ERC1155 bug fix, full ERC721 checkpointable support
Browse files Browse the repository at this point in the history
  • Loading branch information
solimander committed Jan 15, 2024
1 parent e3e7d09 commit a8e4bdc
Show file tree
Hide file tree
Showing 16 changed files with 79 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ mod EthereumBalanceOfERC1155GovernancePowerStrategy {
let slot_index = *params.at(1);
let token_id = *params.at(2);

let mut mapping_keys = array![user.into(), token_id.into()];
let mut mapping_keys = array![token_id.into(), user.into()];
let valid_slot = get_nested_slot_key(slot_index.into(), mapping_keys.span());

let governance_power = SingleSlotProof::get_slot_value(
Expand Down
2 changes: 1 addition & 1 deletion packages/prop-house-protocol/deployments/mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"allowlistGovPowerStrategy": "0x3daa40ef909961a576f9ba58eb063d5ebc85411063a8b29435f05af6167079c",
"ethBalanceOfGovPowerStrategy": "0x6ddcc94a4225843546a9b118a2733fd924d6b8a6467279cbe6a1aea79daca54",
"ethBalanceOfErc20GovPowerStrategy": "0x196cf5ceba8e98abe1e633d6184cd28c1e1ebd09ea71f89867dd4c5fda97bbe",
"ethBalanceOfErc1155GovPowerStrategy": "0x6d22f17522d6992eb479deb850e96f9454fc2f6c127993ab2ef9d411f467e8",
"ethBalanceOfErc1155GovPowerStrategy": "0x44e3bdffcb6ce36596d0faa4316932c5dc47005b9eaaf0f7ce0f455c98b2e75",
"ethCheckpointableErc721GovPowerStrategy": "0x10f7529ec5df9069a06191deb7cd2c4158c2b59879e2544cb45dc221daff429",
"herodotus": {
"factRegistry": "0x002081b2d3de51f295e7516257f68bd9f06acbc7f19ba49410c100afbe57540f",
Expand Down
2 changes: 1 addition & 1 deletion packages/prop-house-protocol/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@prophouse/protocol",
"version": "1.0.8",
"version": "1.0.9",
"license": "GPL-3.0",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
Expand Down
4 changes: 2 additions & 2 deletions packages/prop-house-sdk-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@prophouse/sdk-react",
"version": "1.0.17",
"version": "1.0.18",
"description": "Useful tools for interacting with the Prop House protocol from React applications",
"author": "solimander",
"homepage": "https://prop.house",
Expand All @@ -18,7 +18,7 @@
"wagmi": ">=0.9.2"
},
"dependencies": {
"@prophouse/sdk": "1.0.22"
"@prophouse/sdk": "1.0.23"
},
"devDependencies": {
"react": "^17.0.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/prop-house-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@prophouse/sdk",
"version": "1.0.23",
"version": "1.0.24",
"description": "Useful tools for interacting with the Prop House protocol",
"author": "solimander",
"homepage": "https://prop.house",
Expand Down Expand Up @@ -32,7 +32,7 @@
"@ethersproject/strings": "~5.7.0",
"@ethersproject/wallet": "^5.7.0",
"@pinata/sdk": "^2.1.0",
"@prophouse/protocol": "1.0.7",
"@prophouse/protocol": "1.0.8",
"bn.js": "^5.2.1",
"ethereumjs-fork-block": "^4.2.4",
"ethereumjs-fork-common": "^3.1.3",
Expand Down
6 changes: 6 additions & 0 deletions packages/prop-house-sdk/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export const BALANCE_OF_ERC1155_FUNC = 'function balanceOf(address account, uint
// prettier-ignore
export const GET_CURRENT_VOTES_FUNC = 'function getCurrentVotes(address account) external view returns (uint96)';

/**
* The `numCheckpoints` function signature.
*/
// prettier-ignore
export const NUM_CHECKPOINTS_FUNC = 'function numCheckpoints(address account) external view returns (uint32)';

/**
* The address used to query `balanceOf` functions to detect the slot index.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class BalanceOfERC1155Handler extends SingleSlotProofHandler<BalanceOfERC
const strategy = await this.getStrategyAddressAndParams(strategyId);
const [contractAddress, slotIndex, tokenId] = strategy.params;

const slotKey = encoding.getNestedSlotKey([account, tokenId], slotIndex);
const slotKey = encoding.getNestedSlotKey([tokenId, account], slotIndex);
const slotKeyU256 = splitUint256.SplitUint256.fromHex(slotKey);

const block = await this.getBlockNumberForTimestamp(timestamp);
Expand All @@ -98,7 +98,7 @@ export class BalanceOfERC1155Handler extends SingleSlotProofHandler<BalanceOfERC
const strategy = await this.getStrategyAddressAndParams(strategyId);
const [contractAddress, slotIndex, tokenId] = strategy.params;

const slotKey = encoding.getNestedSlotKey([account, tokenId], slotIndex);
const slotKey = encoding.getNestedSlotKey([tokenId, account], slotIndex);

const block = await this.getBlockNumberForTimestamp(timestamp);
const storageHash = await this.getStorageHash(contractAddress, block);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SingleSlotProofHandler } from './base';
import { encoding, splitUint256, storageProofs } from '../../utils';
import { BigNumber } from '@ethersproject/bignumber';
import { Contract } from '@ethersproject/contracts';
import { GET_CURRENT_VOTES_FUNC } from '../../constants';
import { GET_CURRENT_VOTES_FUNC, NUM_CHECKPOINTS_FUNC } from '../../constants';
import { Call } from 'starknet';

export class CheckpointableERC721Handler extends SingleSlotProofHandler<CheckpointableERC721Config> {
Expand Down Expand Up @@ -68,10 +68,15 @@ export class CheckpointableERC721Handler extends SingleSlotProofHandler<Checkpoi
const numCheckpointsSlotKey = encoding.getSlotKey(account, numCheckpointsSlotIndex);
const numCheckpointsSlotKeyU256 = splitUint256.SplitUint256.fromHex(numCheckpointsSlotKey);

const checkpointsSlotKey = encoding.getSlotKey(account, checkpointsSlotIndex);
const block = await this.getBlockNumberForTimestamp(timestamp);
const numCheckpoints = await this.contractFor(contractAddress).numCheckpoints(account, {
blockTag: block,
});
const checkpointToQuery = `0x${(Number(numCheckpoints) - 1).toString(16)}`;

const checkpointsSlotKey = encoding.getNestedSlotKey([account, checkpointToQuery], checkpointsSlotIndex);
const checkpointsSlotKeyU256 = splitUint256.SplitUint256.fromHex(checkpointsSlotKey);

const block = await this.getBlockNumberForTimestamp(timestamp);
const [numCheckpointsProofInputs, checkpointsProofInputs] = await Promise.all([
this.fetchProofInputs(contractAddress, numCheckpointsSlotKey, block),
this.fetchProofInputs(contractAddress, checkpointsSlotKey, block),
Expand Down Expand Up @@ -168,6 +173,6 @@ export class CheckpointableERC721Handler extends SingleSlotProofHandler<Checkpoi
* @param token The token address
*/
private contractFor(token: string) {
return new Contract(token, [GET_CURRENT_VOTES_FUNC], this._evm);
return new Contract(token, [GET_CURRENT_VOTES_FUNC, NUM_CHECKPOINTS_FUNC], this._evm);
}
}
2 changes: 1 addition & 1 deletion packages/prop-house-subgraph/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export function getGovPowerStrategyType(addr: string): string {
if (addr == '0x196cf5ceba8e98abe1e633d6184cd28c1e1ebd09ea71f89867dd4c5fda97bbe') {
return GovPowerStrategyType.BALANCE_OF_ERC20;
}
if (addr == '0x6d22f17522d6992eb479deb850e96f9454fc2f6c127993ab2ef9d411f467e8') {
if (addr == '0x6d22f17522d6992eb479deb850e96f9454fc2f6c127993ab2ef9d411f467e8' || addr == '0x44e3bdffcb6ce36596d0faa4316932c5dc47005b9eaaf0f7ce0f455c98b2e75') {
return GovPowerStrategyType.BALANCE_OF_ERC1155;
}
if (addr == '0x10f7529ec5df9069a06191deb7cd2c4158c2b59879e2544cb45dc221daff429') {
Expand Down
2 changes: 1 addition & 1 deletion packages/prop-house-webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"@fortawesome/react-fontawesome": "^0.1.17",
"@nouns/prop-house-wrapper": "1.0.0",
"@prophouse/protocol": "1.0.6",
"@prophouse/sdk-react": "1.0.15",
"@prophouse/sdk-react": "1.0.17",
"@rainbow-me/rainbowkit": "^1.3.0",
"@reduxjs/toolkit": "^1.7.0",
"@supabase/supabase-js": "^2.39.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,13 @@ const AddVoter: React.FC<{
...newVoter,
type: VotingStrategyType.BALANCE_OF,
asset: AssetType.ERC721,
}) ;
});
} else if (selectedType === StrategyType.ERC20) {
setVoter({
...newVoter,
type: VotingStrategyType.BALANCE_OF_ERC20,
asset: AssetType.ERC20,
}) ;
});
} else if (selectedType === StrategyType.ERC1155) {
setVoter({
...newVoter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,17 @@ const ProposingStrategiesDisplay: React.FC<{
</>
);

if (stratType === GovPowerStrategyType.CHECKPOINTABLE_ERC721)
copy = (
<>
Owners or delegates of the{' '}
<a href={buildEtherscanPath(strat.tokenAddress)} target="_blank" rel="noreferrer">
{display(strat.tokenAddress)}
</a>{' '}
token can propose. {propThreshold > 1 && `${propThreshold} tokens required`}
</>
);

if (stratType === GovPowerStrategyType.UNKNOWN) copy = <>Error reading proposing strategy</>;

return formattedContent(copy);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ const VotingStrategiesDisplay: React.FC<{
</>
);

if (stratType === GovPowerStrategyType.CHECKPOINTABLE_ERC721)
copy = (
<>
Owners or delegates of the{' '}
<a href={buildEtherscanPath(strat.tokenAddress)} target="_blank" rel="noreferrer">
{display(strat.tokenAddress)}
</a>{' '}
token can vote. {strat.multiplier ? strat.multiplier : 1} vote per token.
</>
);

if (stratType === GovPowerStrategyType.UNKNOWN) copy = <>Error reading voting strategy</>;

return formattedContent(copy);
Expand Down
3 changes: 2 additions & 1 deletion packages/prop-house-webapp/src/hooks/useTokenNames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const useTokenNames = (strategies: ParsedGovPowerStrategy[]): UseTokenNamesResul
const contracts = strategies
.map(strategy => {
const isErc20OrErc721 = strategy.strategyType === GovPowerStrategyType.BALANCE_OF ||
strategy.strategyType === GovPowerStrategyType.BALANCE_OF_ERC20;
strategy.strategyType === GovPowerStrategyType.BALANCE_OF_ERC20 ||
strategy.strategyType === GovPowerStrategyType.CHECKPOINTABLE_ERC721;

if (isErc20OrErc721)
return {
Expand Down
14 changes: 13 additions & 1 deletion packages/prop-house-webapp/src/utils/createVoterStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,22 @@ import {
} from '@prophouse/sdk-react';
import { NewVoter } from '../components/HouseManager/VotersConfig';

/**
* Known ERC721 checkpointable tokens.
*/
const ERC721_CHECKPOINTABLE_TOKENS = ['0x9c8ff314c9bc7f6e59a9d9225fb22946427edc03' /* Nouns */];

const createVoterStrategy = (voter: NewVoter): GovPowerStrategyConfig | null => {
let s: GovPowerStrategyConfig | null = null;

if (voter.type === VotingStrategyType.BALANCE_OF_ERC1155) {
if (voter.type === VotingStrategyType.CHECKPOINTABLE_ERC721 || ERC721_CHECKPOINTABLE_TOKENS.includes(voter.address?.toLowerCase())) {
s = {
strategyType: VotingStrategyType.CHECKPOINTABLE_ERC721,
assetType: AssetType.ERC721,
address: voter.address,
multiplier: voter.multiplier,
};
} else if (voter.type === VotingStrategyType.BALANCE_OF_ERC1155) {
s = {
strategyType: voter.type,
assetType: AssetType.ERC1155,
Expand Down
59 changes: 14 additions & 45 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5978,55 +5978,24 @@
dependencies:
ethers "~5.7.2"

"@prophouse/[email protected].7":
version "1.0.7"
resolved "https://registry.npmjs.org/@prophouse/protocol/-/protocol-1.0.7.tgz#27001fa8b29c469fe26d343f84a99c09c406da15"
integrity sha512-lkMwsYzM6AYxUXSdRmuw6YSmsDxurasi1rg20wvPZmtuMb5jDe5Zei8SMTEJpPW+sPwqecnb6t7/bMUkOttWVw==
"@prophouse/[email protected].8":
version "1.0.8"
resolved "https://registry.npmjs.org/@prophouse/protocol/-/protocol-1.0.8.tgz#745869a4932df727221514ece06563ed7a93a011"
integrity sha512-XSYA5iqrbD2pyZFD3bSoJKFOeQs/9LgElddZ1cOj6UzQhe2xA0e5ZW5aTwGqEW4eIq8Ed6Am8ruNF8SwyAcphA==
dependencies:
ethers "~5.7.2"

"@prophouse/[email protected]":
version "1.0.15"
resolved "https://registry.npmjs.org/@prophouse/sdk-react/-/sdk-react-1.0.15.tgz#a9df1ee3363d0c7f0fe9bcba04a2103f090acf7d"
integrity sha512-CJakH5gWbyi3GVw2sZ29BnHqmow36/urenjKmrwXohTML0EAtYDy8No+fClMRL32UHWvDxMMYBqNR1yU3gEYXg==
dependencies:
"@prophouse/sdk" "1.0.21"

"@prophouse/[email protected]":
version "1.0.21"
resolved "https://registry.npmjs.org/@prophouse/sdk/-/sdk-1.0.21.tgz#c83c532d77d2a696c5795be3ff8880bbb53a4c82"
integrity sha512-ADUwQir+5QezJ/rTTcwTXCy8Ge3SAalV9dAsFOrGhenuW6E7ROUTx4PvC8BXsXdPiY5LgOivLPBYr29KbRQmdw==
"@prophouse/[email protected]":
version "1.0.17"
resolved "https://registry.npmjs.org/@prophouse/sdk-react/-/sdk-react-1.0.17.tgz#5d4b31962156d243197c7144dcf5db5ffee81381"
integrity sha512-96udnh5fIefG7+eYG/n+2WevYYogcQyE4fxYCNxBGy9zyhjUVSuieMWegwzYzRTI8GWPxHCUxFyXpaWXghCaxQ==
dependencies:
"@ethersproject/abi" "~5.7.0"
"@ethersproject/abstract-provider" "~5.7.0"
"@ethersproject/abstract-signer" "~5.7.0"
"@ethersproject/address" "~5.7.0"
"@ethersproject/bignumber" "~5.7.0"
"@ethersproject/bytes" "~5.7.0"
"@ethersproject/constants" "~5.7.0"
"@ethersproject/contracts" "~5.7.0"
"@ethersproject/keccak256" "~5.7.0"
"@ethersproject/providers" "~5.7.0"
"@ethersproject/solidity" "~5.7.0"
"@ethersproject/strings" "~5.7.0"
"@ethersproject/wallet" "^5.7.0"
"@pinata/sdk" "^2.1.0"
"@prophouse/protocol" "1.0.6"
bn.js "^5.2.1"
ethereumjs-fork-block "^4.2.4"
ethereumjs-fork-common "^3.1.3"
graphql "^16.5.0"
graphql-request "5.0.0"
merkletreejs "^0.3.11"
micro-starknet "^0.2.3"
randombytes "^2.1.0"
starknet "5.19.5"
time-ts "^0.1.0"
"@prophouse/sdk" "1.0.23"

"@prophouse/[email protected].22":
version "1.0.22"
resolved "https://registry.npmjs.org/@prophouse/sdk/-/sdk-1.0.22.tgz#276f502f8cb1e9303796072bfba09ba7edf7769c"
integrity sha512-Pq0f+kn6hQfa+Mb2YotFxVern/Dqi+Co5xkomVR1P/tfvUY5Pa2TKmCsQT1AdRBhL8H6KH1vvnq85n3a3iQTgw==
"@prophouse/[email protected].23":
version "1.0.23"
resolved "https://registry.npmjs.org/@prophouse/sdk/-/sdk-1.0.23.tgz#c24716ec419d5ff3acce985c148bfbe6e381c924"
integrity sha512-N/tlB+BHeUmycroErHpu8ZoP+GXFvXgc2Uowbd0HkX+JIqU5GfOP2up4dCJ+3fz6I5rPdqUA5i+G66e2+q73kA==
dependencies:
"@ethersproject/abi" "~5.7.0"
"@ethersproject/abstract-provider" "~5.7.0"
Expand All @@ -6042,7 +6011,7 @@
"@ethersproject/strings" "~5.7.0"
"@ethersproject/wallet" "^5.7.0"
"@pinata/sdk" "^2.1.0"
"@prophouse/protocol" "1.0.7"
"@prophouse/protocol" "1.0.8"
bn.js "^5.2.1"
ethereumjs-fork-block "^4.2.4"
ethereumjs-fork-common "^3.1.3"
Expand Down

0 comments on commit a8e4bdc

Please sign in to comment.