Comment on page
🤖

Usage and Contract

Overview

The Veryfi contract facilitates the process of verifying ownership of tokens across various blockchain networks. This includes NFTs, ERCs, staked tokens, or any other tokens that implement the balanceOf function. The contract works by interacting with the Morpheus oracle to fetch crosschain data about the user's balance.

Veryfi Deployed Addresses

Sepolia/Optimism/Arbitrum/Base 0x0000Ad609D5167e87DC7456fbf6AB5FBf2fB08a7

Bootstrap NFT Gatekeeper contract using Veryfi for Ethereum

Here's a sample contract to show how easy it is to Veryfi assets. Simply put in the Veryfi address for the chain you're using, the NFT address for your NFT to check ownership, and set the ChainID for the NFT you're looking to verify ownership and you're ready to use Veryfi.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
interface ICrosschainLookup {
function getBalance(address target, address TOKEN, uint chainID) external payable;
function userBalance(uint chainID, address user, address token) external view returns (uint256);
function fee() external view returns (uint);
}
contract NFTWhitelister {
ICrosschainLookup public veryfi;
address public NFT; // The NFT we want to check
mapping(address => bool) public whitelisted; // To store whitelisted users
uint public chainID = 1;
constructor(address _veryfiAddress, address _desiredNFT, uint ID) {
veryfi = ICrosschainLookup(_veryfiAddress);
NFT = _desiredNFT;
chainID = ID;
}
// Request to check if a holder possesses the desired NFT on another chain
function requestNFTVerification(address holder, uint chainID) external payable {
uint feeRequired = veryfi.fee();
require(msg.value >= feeRequired, "Insufficient fee sent");
veryfi.getBalance{value: feeRequired}(holder, NFT, chainID);
}
// Set the balance for a user (typically called after the balance has been fetched)
function setBalanceForUser(address holder, uint chainID) external {
veryfi.setBalance(holder, NFT, chainID);
}
// Whitelist the user if they possess the desired NFT on another chain
function whitelistUser(address holder, uint chainID) external {
uint256 nftBalance = veryfi.userBalance(chainID, holder, NFT);
require(nftBalance > 0, "Holder does not possess the desired NFT");
whitelisted[holder] = true;
}
function isWhitelisted(address holder) external view returns (bool) {
return whitelisted[holder];
}
}
You can also skip the request verification by simply getting your users to go to https://veryfi.xyz/ to verify their assets first. Then you can simply
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
interface ICrosschainLookup {
function userBalance(uint chainID, address user, address token) external view returns (uint256);
}
contract NFTWhitelister {
mapping(address => bool) public whitelisted; // To store whitelisted users
// Whitelist the user if they possess the desired NFT on another chain
// 1 assumes ETH for chainID
function whitelistUser(address holder) external {
uint256 nftBalance = ICrosschainLookup(veryfiADDRSHERE).userBalance(1, holder, NFTADDRESSHERE);
require(nftBalance > 0, "Holder does not possess the desired NFT");
whitelisted[holder] = true;
}
function isWhitelisted(address holder) external view returns (bool) {
return whitelisted[holder];
}
}

Contract Interface

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
interface ICrosschainLookup {
function getMyBalance(address TOKEN, uint chainID) external payable;
function getBalance(address target, address TOKEN, uint chainID) external payable;
function setMyBalance(address token, uint chainID) external;
function setBalance(address target, address token, uint chainID) external;
function userBalance(uint chainID, address user, address token) external view returns (uint256);
function userBalanceFeed(uint chainID, address user, address token) external view returns (uint256);
function fee() external view returns (uint256);
}

ICrosschainLookup Interface Documentation

Description

ICrosschainLookup is an interface for querying and setting user balances across different blockchain networks. The contract allows users to retrieve their own balance or the balance of other users for a specific token and chain ID. The balances are fetched from external sources and stored within the contract.

Functions

1. getMyBalance
function getMyBalance(address TOKEN, uint chainID) external payable;
Parameters:
  • TOKEN (type: address): The contract address of the token you want to query the balance for.
  • chainID (type: uint): The ID of the blockchain network you're querying. If set to 0, it defaults to 1.
Description: Allows the caller to query their own balance for a specific token on a specific blockchain network. The function requires a fee to be sent along with the transaction.
2. getBalance
function getBalance(address target, address TOKEN, uint chainID) external payable;
Parameters:
  • target (type: address): The address of the user whose balance you want to query.
  • TOKEN (type: address): The contract address of the token you want to query the balance for.
  • chainID (type: uint): The ID of the blockchain network you're querying. If set to 0, it defaults to 1.
Description: Allows the caller to query the balance of a specific user for a specific token on a specific blockchain network. The function requires a fee to be sent along with the transaction.
3. setMyBalance
function setMyBalance(address token, uint chainID) external;
Parameters:
  • token (type: address): The contract address of the token for which you've previously fetched the balance.
  • chainID (type: uint): The ID of the blockchain network you've fetched the balance from.
Description: Allows the caller to set their balance for a specific token on a specific blockchain network, after they've fetched it using getMyBalance.
4. setBalance
function setBalance(address target, address token, uint chainID) external;
Parameters:
  • target (type: address): The address of the user whose balance you've fetched and want to set.
  • token (type: address): The contract address of the token for which you've fetched the balance.
  • chainID (type: uint): The ID of the blockchain network you've fetched the balance from.
Description: Allows the caller to set the balance of a specific user for a specific token on a specific blockchain network, after they've fetched it using getBalance.
5. userBalance
function userBalance(uint chainID, address user, address token) external view returns (uint256);
Parameters:
  • chainID (type: uint): The ID of the blockchain network you want to get the stored balance from.
  • user (type: address): The address of the user whose stored balance you want to retrieve.
  • token (type: address): The contract address of the token you want to get the stored balance for.
Returns:
  • uint256: The stored balance of the user for the specified token on the specified blockchain network.
Description: Returns the stored balance of a specific user for a specific token on a specific blockchain network.
6. userBalanceFeed
function userBalanceFeed(uint chainID, address user, address token) external view returns (uint256);
Parameters:
  • chainID (type: uint): The ID of the blockchain network you want to get the feed ID from.
  • user (type: address): The address of the user whose feed ID you want to retrieve.
  • token (type: address): The contract address of the token you want to get the feed ID for.
Returns:
  • uint256: The feed ID associated with the user's balance fetch operation for the specified token on the specified blockchain network.
Description: Returns the feed ID associated with a user's balance fetch operation for a specific token on a specific blockchain network. This feed ID can be used to fetch the balance from an external source.

7. fee

function fee() external view returns (uint256);
Returns:
  • uint256: The current fee amount required to query balances.
Description: Returns the current fee amount (in wei) that users need to send along with their transaction when querying their balance or the balance of another user. This fee is set by the contract owner and is used to compensate for the oracle costs associated with querying balances from external sources.
Notes:
  • Always double-check the chainID to make sure you're querying the correct blockchain network.
  • Fees are required for balance fetch operations (getMyBalance and getBalance), ensure you send the correct fee amount when calling these functions.
  • setBalance can only be used once the oracle has submitted the balance to the network, this usually takes between 15-60s. You can send a larger fee using getBalance to ensure the oracle will process the request during high use. You can also explore the Morpheus docs here for being able to reping requests, increase the bounty to fill a request. https://docs.scry.finance/docs/morpheus/use-request-feeds

Supported Chains

Ethereum Chain ID 0

Optimism Chain ID 10

Arbitrum Chain ID 42161

Base Chain ID 8453

Polygon Chain ID 137

CrosschainLookup.sol

Constructor

The constructor initializes the RPC mapping with default RPC endpoints for various blockchain networks. It also sets the owner to the address that deploys the contract.

Functions and Specs

1. getMyBalance(address TOKEN, uint chainID) public payable

Fetches the balance of the caller's token on a specific chain.
  • TOKEN: Address of the token contract.
  • chainID: The ID of the blockchain network. If set to 0, it defaults to 1 (Ethereum mainnet).

2. getBalance(address target, address TOKEN, uint chainID) public payable

Fetches the balance of a specified address's token on a particular chain.
  • target: Address of the user whose balance needs to be fetched.
  • TOKEN: Address of the token contract.
  • chainID: The ID of the blockchain network. If set to 0, it defaults to 1 (Ethereum mainnet).

3. addressToBytes(address _address) public pure returns (bytes memory)

Converts an address to bytes.
  • _address: The address to be converted.

4. bytesToHexString(bytes memory data) public pure returns (string memory)

Converts bytes data to a hex string.
  • data: The bytes data to be converted.

5. changeOwnerFEEAndRPC(address Own, uint nfee, string memory newRPC, uint i) public

Changes the contract owner, the fee, and the RPC endpoint of a specific chain. Only the owner can call this function.
  • Own: The new owner's address.
  • nfee: The new fee value.
  • newRPC: The new RPC endpoint.
  • i: The chain ID for which the RPC endpoint needs to be updated.

6. setMyBalance(address token, uint chainID) public

Sets the balance of the caller's token on a specific chain.
  • token: Address of the token contract.
  • chainID: The ID of the blockchain network. If set to 0, it defaults to 1 (Ethereum mainnet).

7. setBalance(address target, address token, uint chainID) public

Sets the balance of a specified address's token on a specific chain.
  • target: Address of the user whose balance needs to be set.
  • token: Address of the token contract.
  • chainID: The ID of the blockchain network. If set to 0, it defaults to 1 (Ethereum mainnet).

Important Notes

  1. 1.
    The contract relies on the Morpheus oracle to fetch crosschain data. The oracle's results are then stored in the userBalance mapping.
  2. 2.
    The contract requires a fee (fee) to be paid when making requests to the Morpheus oracle.
  3. 3.
    The owner of the contract has the ability to change the contract's fee, the owner address itself, and the RPC endpoints for different chains.