Address <> user score contract

Get user quality score for an address connected to a Farcaster profile.

📘

Read prior context on user scores here

User scores are particularly useful if anonymous addresses are interacting with your contract and you want to restrict interaction to high quality addresses. Neynar already supports user quality scores offchain (read more here), this brings them onchain and makes it available to smart contracts. Now, on the Base Mainnet and Sepolia testnet, smart contracts can query the fid linked to any ETH address and the quality score for that FID.

Contract

ChainAddressDeploy Transaction
Base Mainnet0xd3C43A38D1D3E47E9c420a733e439B03FAAdebA80x059259c15f660a4b5bd10695b037692654415f60e13569c7a06e99cfd55a54b0
Base Sepolia0x7104CFfdf6A1C9ceF66cA0092c37542821C1EA500xfdf68b600f75b4688e5432442f266cb291b9ddfe2ec05d2fb8c7c64364cf2c73
  • Read the Proxy Contract on the Base Explorer (link). This is the upgradeable proxy contract you should use.
  • User score code on the Base Explorer (link). This is an upgradeable implementation contract. There is no state here. This is the code that the proxy contract is currently using.

Interface

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

interface INeynarUserScoresReader {
    function getScore(address verifier) external view returns (uint24 score);
    function getScoreWithEvent(address verifier) external returns (uint24 score);
    function getScores(address[] calldata verifiers) external view returns (uint24[] memory scores);

    function getScore(uint256 fid) external view returns (uint24 score);
    function getScoreWithEvent(uint256 fid) external returns (uint24 score);
    function getScores(uint256[] calldata fids) external view returns (uint24[] memory scores);
}

If the getScore call returns 0there is no user score for that address.

If you can spare the gas and would like us to know that you are using our contract, please use getScoreWithEvent.

Sample use

A simple example of a HelloWorld contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

interface INeynarUserScoresReader {
    function getScore(address verifier) external view returns (uint24 score);
    function getScoreWithEvent(address verifier) external returns (uint24 score);
    function getScores(address[] calldata verifiers) external view returns (uint24[] memory scores);

    function getScore(uint256 fid) external view returns (uint24 score);
    function getScoreWithEvent(uint256 fid) external returns (uint24 score);
    function getScores(uint256[] calldata fids) external view returns (uint24[] memory scores);
}

contract HelloWorld {
    INeynarUserScoresReader immutable verifications;
  
    constructor(INeynarUserScoresReader _userScores) {
       userScores = _userScores;
    }
  
    function requireHighScore() public view returns (uint256) {
        uint256 score = userScores.getScoreWithEvent(msg.sender);
      
        if (score < 950000) {
            revert("!top 5% percentile account");
        }

        return score;
    }
}

Future

This experiment will see what we can unlock by bringing more Farcaster data on-chain. If you build something using this, please reach out. We want to hear what you're building and see how we can make it easier.

Further reading