diff --git a/src/constants/HubV3ABI.js b/src/constants/HubV3ABI.js new file mode 100644 index 0000000..4b36b4e --- /dev/null +++ b/src/constants/HubV3ABI.js @@ -0,0 +1,33 @@ +export default [ + "constructor(address)", + "event Approval(address indexed,address indexed,uint256 indexed)", + "event ApprovalForAll(address indexed,address indexed,bool)", + "event OwnershipTransferred(address indexed,address indexed)", + "event Transfer(address indexed,address indexed,uint256 indexed)", + "function approve(address,uint256)", + "function balanceOf(address) view returns (uint256)", + "function changeVerifier(address)", + "function collectFees()", + "function fees(bytes32) view returns (uint256)", + "function getApproved(uint256) view returns (address)", + "function getIdentifier(address,bytes32) pure returns (bytes32)", + "function getSBT(address,bytes32) view returns (tuple(uint256,uint256[],bool))", + "function isApprovedForAll(address,address) view returns (bool)", + "function name() view returns (string)", + "function owner() view returns (address)", + "function ownerOf(uint256) view returns (address)", + "function renounceOwnership()", + "function revokeSBT(address,bytes32)", + "function safeTransferFrom(address,address,uint256)", + "function safeTransferFrom(address,address,uint256,bytes)", + "function sbtOwners(bytes32) view returns (uint256, bool)", + "function sendSBT(bytes32,uint256,uint256,uint256,uint256,uint256[],bytes) payable", + "function setApprovalForAll(address,bool)", + "function setFee(bytes32,uint256)", + "function supportsInterface(bytes4) view returns (bool)", + "function symbol() view returns (string)", + "function tokenURI(uint256) view returns (string)", + "function transferFrom(address,address,uint256)", + "function transferOwnership(address)", + "function usedNullifiers(uint256) view returns (bool)", +]; diff --git a/src/constants/misc.js b/src/constants/misc.js index c551864..eb6c886 100644 --- a/src/constants/misc.js +++ b/src/constants/misc.js @@ -1 +1,12 @@ export const defaultActionId = 123456789; + +export const hubV3Address = "0x06E370E885C994F13111F0329e0A85afA57b4074"; +export const hubV3Chain = 10; + +export const govIdIssuerAddress = + "0x03fae82f38bf01d9799d57fdda64fad4ac44e4c2c2f16c5bf8e1873d0a3e1993"; +export const phoneIssuerAddress = + "0x2998cab3d07a64315f1e8399ecef60a19f478231663f8740703bd30a42a91ed4"; + +export const v3KYCSybilResistanceCircuitId = + "0x729d660e1c02e4e419745e617d643f897a538673ccf1051e093bbfa58b0a120b"; diff --git a/src/services/sybil-resistance.js b/src/services/sybil-resistance.js index d2ce2d1..73f35c7 100644 --- a/src/services/sybil-resistance.js +++ b/src/services/sybil-resistance.js @@ -7,7 +7,13 @@ import { sybilResistanceAddrsByNetwork, sybilResistancePhoneAddrsByNetwork, } from "../constants/contractAddresses.js"; +import { + hubV3Address, + govIdIssuerAddress, + v3KYCSybilResistanceCircuitId, +} from "../constants/misc.js"; import AntiSybilStoreABI from "../constants/AntiSybilStoreABI.js"; +import HubV3ABI from "../constants/HubV3ABI.js"; async function sybilResistanceGovId(req, res) { try { @@ -31,8 +37,8 @@ async function sybilResistanceGovId(req, res) { } // Check blocklist first - const result = await blocklistGetAddress(address); - if (result.Item) { + const blockListResult = await blocklistGetAddress(address); + if (blockListResult.Item) { return res.status(200).json({ result: false }); } @@ -40,6 +46,7 @@ async function sybilResistanceGovId(req, res) { const provider = providers[network]; + // Check v1/v2 contract const v1ContractAddr = sybilResistanceAddrsByNetwork[network]; const v1Contract = new ethers.Contract( v1ContractAddr, @@ -48,7 +55,29 @@ async function sybilResistanceGovId(req, res) { ); const isUnique = await v1Contract.isUniqueForAction(address, actionId); - return res.status(200).json({ result: isUnique }); + if (isUnique || network !== "optimism") { + return res.status(200).json({ result: isUnique }); + } + + // Check v3 contract + try { + const hubV3Contract = new ethers.Contract(hubV3Address, HubV3ABI, provider); + + const sbt = await hubV3Contract.getSBT(address, v3KYCSybilResistanceCircuitId); + + const publicValues = sbt[1]; + const issuerAddress = publicValues[4]; + + return res + .status(200) + .json({ result: govIdIssuerAddress === issuerAddress.toHexString() }); + } catch (err) { + if ((err.errorArgs?.[0] ?? "").includes("SBT is expired")) { + return res.status(200).json({ result: false }); + } + + throw err; + } } catch (err) { console.log(err); logWithTimestamp(