Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI allowlist #410

Merged
merged 76 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
38b29b4
feat: AllowListInput
Lucianosc Sep 7, 2024
922eab2
add AllowList in PoolForm
Lucianosc Sep 7, 2024
2a6428e
feat AllowList finished
Lucianosc Sep 8, 2024
2f28cf9
Merge commit 'e819f80af6b882b5abb5492dbf73bc755f8bce4f' into ui-allow…
Lucianosc Sep 8, 2024
d788a47
fix PoolForm
Lucianosc Sep 9, 2024
9aca812
fix Button tooltip
Lucianosc Sep 9, 2024
308d167
add subgraph query
Lucianosc Sep 9, 2024
b0fd0c9
feat useCheckllowList
Lucianosc Sep 9, 2024
3843afc
add check allow list implementation
Lucianosc Sep 9, 2024
4fe4fcc
fix sybil resistance order section
Lucianosc Sep 9, 2024
5ea06c2
Merge remote-tracking branch 'origin/allowlist-feature' into ui-allow…
Lucianosc Sep 12, 2024
696bf95
PR fixes
Lucianosc Sep 12, 2024
a48dd93
fixes & clean up
Lucianosc Sep 12, 2024
dc3669f
add sybil resistance restriction for pooltypes
Lucianosc Sep 13, 2024
a1565d6
Change abi to v0_1
Corantin Sep 13, 2024
5b8ed37
Merge branch 'allowlist-feature' into ui-allowlist
Corantin Sep 15, 2024
c128f8a
Merge remote-tracking branch 'origin/allowlist-feature' into ui-allow…
Corantin Sep 16, 2024
3cf4fa7
Merge remote-tracking branch 'origin/dev' into ui-allowlist
Lucianosc Sep 17, 2024
eb4a3ca
wip add sybil resistance inputs in PoolEditForm
Lucianosc Sep 19, 2024
07ae011
minor fixes
Lucianosc Sep 19, 2024
7021296
add fetch passport score in PoolEditForm
Lucianosc Sep 19, 2024
7030770
Merge remote-tracking branch 'origin/dev' into ui-allowlist
Lucianosc Sep 23, 2024
e3acea6
final fix
Lucianosc Sep 24, 2024
a0c199d
add modifyThreshold
Lucianosc Sep 25, 2024
2b2ba3e
build fix
Lucianosc Sep 25, 2024
b99a4d2
Merge branch 'allowlist-feature' into ui-allowlist
Lucianosc Sep 25, 2024
8dad1c6
Merge branch 'allowlist-feature' into ui-allowlist
Corantin Sep 25, 2024
5efd3b6
Merge branch 'allowlist-feature' into ui-allowlist
Corantin Sep 25, 2024
61bcd14
Merge branch 'allowlist-feature' into ui-allowlist
Corantin Sep 26, 2024
81409d7
fix PoolEditForm
Lucianosc Sep 26, 2024
a8d32e3
Fix
Corantin Sep 29, 2024
77afbe6
Merge remote-tracking branch 'origin/ui-allowlist' into ui-allowlist
Lucianosc Oct 1, 2024
ba9811a
minor fix PoolForm
Lucianosc Oct 1, 2024
02a9a01
minor fixes
Lucianosc Oct 1, 2024
3af644b
Fix abi function selection + fix pasport threshold not being added to…
Corantin Oct 3, 2024
c703e3e
Merge remote-tracking branch 'origin/allowlist-feature' into ui-allow…
Corantin Oct 3, 2024
fa2684e
Test change precision to 14
Corantin Oct 3, 2024
5233092
Merge branch 'allowlist-feature' into ui-allowlist
Corantin Oct 4, 2024
40d7c3a
Revert "Test change precision to 14"
Corantin Oct 4, 2024
c1d2ad1
Fix typing from subgraph
Corantin Oct 4, 2024
27ee5a4
Update prod subgraph
Corantin Oct 4, 2024
5b8ad9b
Fix allowing all not set in form value
Corantin Oct 4, 2024
c69070c
Merge branch 'dev' into ui-allowlist
Corantin Oct 9, 2024
7b6a1e5
Build contracts
Corantin Oct 9, 2024
602278f
refactor: update type definitions and streamline imports.
Corantin Oct 9, 2024
3cb0e74
Merge branch 'allowlist-feature' into ui-allowlist
Corantin Oct 9, 2024
870572d
feat: Enhance subgraph schema for collateral management.
Corantin Oct 9, 2024
913120d
:recycle: Refactor GoBackButton navigation logic
Corantin Oct 10, 2024
92e0247
:art: Updated styling for MarkdownEditor
Corantin Oct 10, 2024
4d5bc3d
:recycle: Simplified import and removed unused code
Corantin Oct 10, 2024
fb8ede5
Lock file update
Corantin Oct 10, 2024
62ba2c4
Merge from dev
Corantin Oct 10, 2024
272d611
:bug: Fixed null poolTokenAddress issue
Corantin Oct 10, 2024
de0aa83
Merge branch 'allowlist-feature' into ui-allowlist
Corantin Oct 10, 2024
cc7df62
Merge pull request #464 from 1Hive/enhance-back-button
Corantin Oct 10, 2024
6a966c9
Merge remote-tracking branch 'origin/dev' into ui-allowlist
Corantin Oct 10, 2024
9c2e535
Auto stash before merge of "ui-allowlist" and "origin/dev"
Corantin Oct 10, 2024
0868c93
:recycle: Refactored form input components
Corantin Oct 10, 2024
7880a77
:recycle: Refactored form components for better reusability
Corantin Oct 10, 2024
fbf40ca
Fix readme
Corantin Oct 10, 2024
ae99964
:sparkles: Added cron job and API key validation
Corantin Oct 11, 2024
baf8546
:truck: Moved .vercel.json to apps/web for vercel detection
Corantin Oct 11, 2024
30a8a99
:truck: Move to web folder and rename to vercel.json
Corantin Oct 11, 2024
f3b4175
:recycle: Refactored code to support multiple chains
Corantin Oct 11, 2024
c556a98
:lock: Updated API key handling
Corantin Oct 11, 2024
9670645
:alarm_clock: Updated job schedule in vercel.json
Corantin Oct 11, 2024
8cd160d
:recycle: Refactored daily job route for multi-chain support
Corantin Oct 11, 2024
a77169a
Merge from dev
Corantin Oct 11, 2024
6b98db6
:recycle: Refactored code for multi-chain support and improved UI
Corantin Oct 14, 2024
906f077
Build contracts
Corantin Oct 14, 2024
baea356
:recycle: Refactored code to improve passport scoring system
Corantin Oct 14, 2024
d6971e5
:rotating_light: Fix compile
Corantin Oct 14, 2024
b3e58da
:recycle: Updated PoolGovernance component
Corantin Oct 14, 2024
c707f61
:rotating_light: Fix compile
Corantin Oct 14, 2024
420f7cc
:recycle: Refactored error messages and improved code readability
Corantin Oct 15, 2024
eaea92f
:recycle: Refactored code for better readability and efficiency
Corantin Oct 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
d# Gardens v2
# Gardens v2

> Gardens is a **coordination platform**
> that fosters **vibrant ecosystems of shared wealth**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { useMetadataIpfsFetch } from "@/hooks/useIpfsFetch";
import { useSubgraphQuery } from "@/hooks/useSubgraphQuery";
import { alloABI } from "@/src/generated";
import { PoolTypes, ProposalStatus } from "@/types";
import { abiWithErrors } from "@/utils/abiWithErrors";
import { abiWithErrors } from "@/utils/abi";
import { useErrorDetails } from "@/utils/getErrorName";
import { prettyTimestamp } from "@/utils/text";

Expand Down Expand Up @@ -124,7 +124,7 @@ export default function Page({
abi: abiWithErrors(alloABI),
functionName: "distribute",
contractName: "Allo",
fallbackErrorMessage: "Error executing proposal. Please try again.",
fallbackErrorMessage: "Error executing proposal, please report a bug.",
onConfirmations: () => {
publish({
topic: "proposal",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { useCollectQueryParams } from "@/contexts/collectQueryParams.context";
import { useMetadataIpfsFetch } from "@/hooks/useIpfsFetch";
import { useSubgraphQuery } from "@/hooks/useSubgraphQuery";
import { PoolTypes } from "@/types";
import { CV_SCALE_PRECISION } from "@/utils/numbers";

export const dynamic = "force-dynamic";

Expand All @@ -28,7 +27,7 @@ export default function Page({
params: { chain: string; poolId: number; garden: string };
}) {
const searchParams = useCollectQueryParams();

const { data, refetch, error } = useSubgraphQuery<getPoolDataQuery>({
query: getPoolDataDocument,
variables: { poolId: poolId, garden: garden },
Expand Down Expand Up @@ -109,12 +108,9 @@ export default function Page({
return <div className="mt-52 text-center">Pool {poolId} not found</div>;
}

const pointSystem = data.cvstrategies?.[0].config.pointSystem;
const communityAddress = strategyObj.registryCommunity.id as Address;
const alloInfo = data.allos[0];
const poolAmount = strategyObj.poolAmount as number;
const spendingLimitPct =
(Number(strategyObj.config.maxRatio || 0) / CV_SCALE_PRECISION) * 100;

const isEnabled = data.cvstrategies?.[0]?.isEnabled as boolean;

Expand All @@ -128,10 +124,7 @@ export default function Page({
poolId={poolId}
ipfsResult={ipfsResult}
isEnabled={isEnabled}
pointSystem={pointSystem}
chainId={chain}
proposalType={proposalType}
spendingLimitPct={spendingLimitPct}
/>
{isEnabled && (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function Page({

if (!token) {
return (
<div className="mt-96">
<div className="my-40">
<LoadingSpinner />
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// api/add-strategy

import { Params } from "next/dist/shared/lib/router/utils/route-matcher";
import { NextResponse } from "next/server";
import {
createPublicClient,
Expand All @@ -19,26 +20,20 @@ import { getViemChain } from "@/utils/web3";

const LIST_MANAGER_PRIVATE_KEY = process.env.LIST_MANAGER_PRIVATE_KEY;

const CHAIN_ID = process.env.CHAIN_ID ? parseInt(process.env.CHAIN_ID) : 1337;
const LOCAL_RPC = "http://127.0.0.1:8545";

const RPC_URL = getConfigByChain(CHAIN_ID)?.rpcUrl ?? LOCAL_RPC;
export async function POST(req: Request, { params }: Params) {
const apiKey = req.headers.get("Authorization");
const { chain } = params;

const PASSPORT_SCORER_ADDRESS = getConfigByChain(CHAIN_ID)
?.passportScorer as Address;

const client = createPublicClient({
chain: getViemChain(CHAIN_ID),
transport: http(RPC_URL),
});

const walletClient = createWalletClient({
account: privateKeyToAccount(`${LIST_MANAGER_PRIVATE_KEY}` as Address),
chain: getViemChain(CHAIN_ID),
transport: custom(client.transport),
});
if (apiKey !== process.env.CRON_SECRET) {
console.error("Unauthorized", {
req: req.url,
chain,
});
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}

export async function POST(req: Request) {
const { strategy, threshold } = await req.json();

if (!strategy || !threshold) {
Expand All @@ -52,6 +47,22 @@ export async function POST(req: Request) {
}

try {
const RPC_URL = getConfigByChain(chain)?.rpcUrl ?? LOCAL_RPC;

const PASSPORT_SCORER_ADDRESS = getConfigByChain(chain)
?.passportScorer as Address;

const client = createPublicClient({
chain: getViemChain(chain),
transport: http(RPC_URL),
});

const walletClient = createWalletClient({
account: privateKeyToAccount(`${LIST_MANAGER_PRIVATE_KEY}` as Address),
chain: getViemChain(chain),
transport: custom(client.transport),
});

// Get registryCommunity address from CVStrategy
let registryCommunityAddress: Address;
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// api/passport-oracles/daily-job

import { Params } from "next/dist/shared/lib/router/utils/route-matcher";
import { NextResponse } from "next/server";
import { gql } from "urql";
import {
Expand All @@ -13,16 +14,11 @@ import { privateKeyToAccount } from "viem/accounts";
import { getConfigByChain } from "@/configs/chains";
import { initUrqlClient } from "@/providers/urql";
import { passportScorerABI } from "@/src/generated";
import { CV_PERCENTAGE_SCALE } from "@/utils/numbers";
import { CV_PASSPORT_THRESHOLD_SCALE } from "@/utils/numbers";
import { getViemChain } from "@/utils/web3";

const LIST_MANAGER_PRIVATE_KEY = process.env.LIST_MANAGER_PRIVATE_KEY ?? "";
const CHAIN_ID = process.env.CHAIN_ID ? parseInt(process.env.CHAIN_ID) : 1337;
const LOCAL_RPC = "http://127.0.0.1:8545";
const RPC_URL = getConfigByChain(CHAIN_ID)?.rpcUrl ?? LOCAL_RPC;
const CONTRACT_ADDRESS = getConfigByChain(CHAIN_ID)?.passportScorer as Address;
const SUBGRAPH = getConfigByChain(CHAIN_ID)?.subgraphUrl as string;
const API_ENDPOINT = "/api/passport/scores";

interface PassportUser {
id: string;
Expand All @@ -42,19 +38,6 @@ interface ApiScore {
stamp_scores: Record<string, number>;
}

const client = createPublicClient({
chain: getViemChain(CHAIN_ID),
transport: http(RPC_URL),
});

const walletClient = createWalletClient({
account: privateKeyToAccount(LIST_MANAGER_PRIVATE_KEY as Address),
chain: getViemChain(CHAIN_ID),
transport: custom(client.transport),
});

const { urqlClient } = initUrqlClient({ chainId: CHAIN_ID });

const query = gql`
query {
passportUsers {
Expand All @@ -67,12 +50,9 @@ const query = gql`
`;

const fetchScoresFromService = async (): Promise<ApiScore[]> => {
const url = new URL(
API_ENDPOINT,
`http://${process.env.HOST ?? "localhost"}:${process.env.PORT ?? 3000}`,
);
const url = `${process.env.VERCEL_URL ? "https://" + process.env.VERCEL_URL : "http://localhost:3000"}/api/passport/scores/`;

const response = await fetch(url.toString(), {
const response = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
Expand Down Expand Up @@ -120,35 +100,45 @@ const compareScores = (
};

const updateScoresOnChain = async (
chain: string,
updates: { userAddress: Address; score: number; lastUpdated: number }[],
) => {
const RPC_URL = getConfigByChain(chain)?.rpcUrl ?? LOCAL_RPC;
const CONTRACT_ADDRESS = getConfigByChain(chain)?.passportScorer as Address;

for (const update of updates) {
const integerScore = Number(update.score) * CV_PERCENTAGE_SCALE;
const data = {
const integerScore = Number(update.score) * CV_PASSPORT_THRESHOLD_SCALE;

const client = createPublicClient({
chain: getViemChain(chain),
transport: http(RPC_URL),
});

const walletClient = createWalletClient({
account: privateKeyToAccount(LIST_MANAGER_PRIVATE_KEY as Address),
chain: getViemChain(chain),
transport: custom(client.transport),
});

const hash = await walletClient.writeContract({
abi: passportScorerABI,
address: CONTRACT_ADDRESS,
functionName: "addUserScore" as const,
args: [
update.userAddress,
{
score: BigInt(integerScore),
lastUpdated: BigInt(Date.now()),
},
] as const,
};

const hash = await walletClient.writeContract(data);
args: [update.userAddress, BigInt(integerScore)] as const,
});
await client.waitForTransactionReceipt({ hash });
}
};

const updateScores = async () => {
const updateScores = async (chain: string) => {
const subgraphUrl = getConfigByChain(chain)?.subgraphUrl as string;
const { urqlClient } = initUrqlClient({ chainId: chain });
const subgraphResponse = await urqlClient
.query<{ passportUsers: PassportUser[] }>(
query,
{},
{
url: SUBGRAPH,
url: subgraphUrl,
requestPolicy: "network-only",
},
)
Expand All @@ -164,17 +154,34 @@ const updateScores = async () => {
const updates = compareScores(subgraphUsers, apiScores);

if (updates.length > 0) {
await updateScoresOnChain(updates);
await updateScoresOnChain(chain, updates);
}

return updates;
};

export async function GET() {
export async function GET(req: Request, { params }: Params) {
const apiKey = req.headers.get("Authorization");
const { chain } = params;

if (apiKey !== process.env.CRON_SECRET) {
console.error("Unauthorized", {
req: req.url,
chain,
});
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}

try {
const updates = await updateScores();
const updates = await updateScores(chain);
return NextResponse.json(
{ message: "Scores updated successfully", updates },
{
message:
updates.length ?
"Scores updated successfully"
: "No updates required",
updates,
},
{ status: 200 },
);
} catch (error) {
Expand Down
Loading
Loading