How do Verifier Nodes Work
Last updated
Last updated
This document is based on the design for alphanet. The mainnet will be similar, but please check this page for any new updates. (06/18/2024)
Bluwhale Smart Contract Design
The overall architecture is divided into four modules: veBluwhale, License NFT, Protocol Service, and Vault. With the exception of the Protocol Service module, each module corresponds to a single smart contract. The Protocol Service module, however, comprises multiple smart contracts (proxy contract, logic contract, settings contract, etc.). The Bluwhale Token contract is not detailed in the architecture diagram as it only implements the basic ERC20 standard.
Vault Contract: This contract manages the assets for the entire Bluwhale protocol. It operates under four roles: foundation, tee staking pool, veBluwhale reward pool, and NFT pool. Each role can only manage its designated funds through specific methods. Additionally, the Vault contract defines the reward release curve to regulate reward fund operations.
veBluwhale Contract: This contract facilitates the exchange between Bluwhale and veBluwhale tokens. Exchanged Bluwhale tokens are stored within the veBluwhale contract. When users make a claim, half of the Bluwhale tokens that have not met the lock-in period are directed to the foundation address within the Vault.
NFT Contract: This contract oversees the purchase and redemption of NFTs by users. The ETH from NFT purchases is stored in the NFT account within the Vault. Upon redemption, 80% of the ETH is returned to the user (with the remaining 20% serving as a channel fee) or exchanged for an equivalent amount of Bluwhale, which is then linearly released back to the user. The exchange of ETH for Bluwhale is managed by the foundation, completed by the Vault contract, and based on Chainlink exchange rates.
Protocol Service Contract: This contract handles the majority of the business logic and includes several components:
Permission Management: admin, tee
System Parameter Management: Managed through the settings contract
Tee-related Operations: stake, unstake, slash
Verifier-related Operations: enter, exit, report active, slash
Delegation Operations: delegate, redelegate, undelegate
Report Operations: attestation, verification
Upon completing data processing, TEE nodes submit the data verification, AI model training result and the TEE attestation to smart contracts on the execution layer.
The smart contracts employ a Verifiable Random Function (VRF) to randomly choose a subset of verifiers for attestation validation.
In cryptography, a verifiable random function (VRF) is a random number generator (RNG) that generates an output that can be cryptographically verified as random. Verifiable randomness is essential to many blockchain applications because its tamper-proof unpredictability enables exciting gameplay, rare NFTs, and unbiased outcomes. As the name suggests, a verifiable random function is defined by its core features: Verifiable, Random, Function.
Verifiers monitor events from the smart contract to initiate the verification process.
Verifiers assess the authenticity of the attestation. For more details, please check SGX Attestation Verification
Based on the outcome, verifiers relay their findings to the smart contract:
If the attestation is invalid, the smart contract penalizes the responsible TEE node by slashing its stake, which is then allocated to the verifiers as additional rewards.
When the attestation is confirmed as valid with over 50% of designated Verifiers, the smart contract distributes not only the consumers' fees but also on-chain rewards among the TEE nodes, verifiers, and data providers.
Implements the standard ERC20 (decimals: 18).
Mints 1 billion tokens to a specified address upon deployment; no further minting is possible afterward.
A non-transferable ERC20 token (decimals: 18), where standard addresses cannot invoke transfer or transferFrom methods.
Only the Vault contract can call transfer, used for distributing user verification rewards.
Locks the Bluwhale Token address upon deployment, which cannot be modified thereafter.
No explicit minting method; veBluwhale can only be minted through 1:1 staking of Bluwhale and is burned upon redemption.
Future governance of the Bluwhale protocol will be enabled by associating the veBluwhale Token address with the governance contract.
Reference: https://docs.Bluwhale.io/Bluwhale-token/utility
Copy
interface IveBluwhale {
/**
* @notice This struct represents information about a Withdraw by the user.
*
* `withdrawer`: address of who initiates this Withdraw.
* `canceledOrClaimed`: Has this Withdraw been canceled or claimed?
* `amount`: The amount of Withdraw initiated by the user.
* `timestamp`: The time this Withdraw was initiated.
*/
struct WithdrawInfo {
address withdrawer;
bool canceledOrClaimed;
uint256 amount;
uint256 timestamp;
}
event Deposit(address depositer, uint256 amount);
event Withdraw(uint64 indexed id, address withdrawer, uint256 amount);
event CancelWithdraw(uint64 indexed id);
event Claim(uint64 id, uint256 amount);
event ClaimBatch(uint64[] ids, uint256 amount);
/**
* @notice convert Bluwhale to veBluwhale by locking Bluwhale in this contract and minting veBluwhale to msg.sender.
* @notice Bluwhale can be converted to veBluwhale with 1:1 ratio through deposit.
* @notice veBluwhale stands for voting-escrow Bluwhale, is a non-transferable token. veBluwhale is mainly used for:
* @notice 1. Bluwhale Protocol governance.
* @notice 2. Incentive to bootstrap incentive layer, e.g., data owners, providers, consumers.
* @notice 3. Used for governance voting in P2E system 'Infinite Play'.
* @notice 4. Used in P2E systems to delegate voting rights to escrow pool owners and receive pool rewards.
* @notice 5. Incentivizes node operators who secure and support the network.
*
* @dev Emits `Deposit`.
*
* @param amount: amount of Bluwhale to be deposited
*/
function deposit(uint256 amount) external;
/**
* @notice convert veBluwhale to Bluwhale, veBluwhale conversion to Bluwhale requires an unlocking period.
* @notice The withdraw rate varies for different unlocking periods,
* @notice with longer unlocking periods resulting in higher withdraw rates, reaching up to 100%.
* @notice Users are required to pay a network channel fee of 1 Bluwhale each time they initiate a Withdraw.
*
* @dev Emits `Withdraw`.
*
* @param amount: amount of veBluwhale to be withdrawn
*/
function withdraw(uint256 amount) external;
/**
* @notice Cancel the Withdraw by withdrawID.
* @notice It can be canceled before the user claims.
* @notice After the operation, the locking veBluwhale is returned to msg.sender.
*
* @dev Emits `CancelWithdraw`.
*
* @param withdrawID: The withdrawID that the user needs to cancel
*/
function cancelWithdraw(uint64 withdrawID) external;
/**
* @notice Return the Bluwhale corresponding to the specified withdrawID to the user.
* @notice The relationship between the user’s Locking Duration and claimable ratio is as follows:
* ----------------------------------------------------
* | Locking Duration (Days) | Claims (Bluwhale) |
* | 15 | 25% |
* | 90 | 60% |
* | 150 | 100% |
* ----------------------------------------------------
* @notice after that, Burn the locking veBluwhale corresponding to the specified withdrawID
* @notice If the Locking Duration is less than 150 days, the remaining Bluwhale will be:
* @notice 1. 50% enter the Bluwhale foundation to maintain network operation.
* @notice 2. 50% will be burned, which makes Bluwhale deflationary.
*
* @dev Emits `Claim`.
*
* @param withdrawID: The withdrawID that the user needs to claim Bluwhale
*/
function claim(uint64 withdrawID) external;
/**
* @notice To claim Bluwhale by withdrawIDs (Batch).
*
* @dev Emits `ClaimBatch`.
*
* @param withdrawIDs: The withdrawIDs that the user needs to claim Bluwhale
*/
function claimBatch(uint64[] calldata withdrawIDs) external;
}
The Vault contract manages funds, distinguishing account permissions where each role can only call methods specific to its permissions.
Except for the foundation address, other addresses must be preset and cannot be changed afterward. The foundation can only operate assets within its designated permissions, ensuring the overall security of Bluwhale Protocol funds.
The Vault contract includes the following account permissions:
Foundation Account: Receives protocol-generated fees (e.g., from NFT redemptions or veBluwhale withdrawals) and acts as a buffer for fund exchanges (e.g., Bluwhale/ETH exchanges required by the system). It also has the authority to initialize rewards accounts.
Tee Staking Account: Requires tee to stake Bluwhale Tokens before submitting attestations. The Vault converts these into veBluwhale Tokens. If a tee submits a malicious attestation, they must compensate the verifier with the staked veBluwhale Tokens.
NFT Account: Locks ETH from NFT purchases (paid through a separate channel, with the Bluwhale foundation locking the ETH into the Vault contract). This ETH is used for redemption or exchanged for the equivalent Bluwhale (via the foundation).
Rewards Account: Pre-funded by the foundation, releasing funds strictly according to a curve (with a fixed daily release of veBluwhale Tokens, decreasing by 25% every six months). For details, refer to Node Rewards.
Copy
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.17;
interface IVault {
event FoundationWithdraw(address token, uint256 amount);
event NftDeposit(uint256 amount);
event NftWithdraw(uint256 amount, bool withBluwhale);
event TeeDeposit(uint256 amount);
event TeeWithdraw(address to, uint256 amount);
event RewardsInit();
event RewardsWithdraw();
event ChangeFoundation(address newFoundation);
event UpdateAggregator(address aggregator);
/**
* @notice Withdraw token by foundation: by specifying the token address and amount.
* @notice Foundation authorities can only withdraw token from their own accounts and cannot operate locked assets.
*
* @dev Emits `FoundationWithdraw`.
*
* @param token: address of withdraw token, nil address is the source token(like eth)
* @param amount: amount of withdraw token
*/
function foundationWithdraw(address token, uint256 amount) external;
/**
* @notice Deposit minter-paid ETH to Vault contract
* @notice Only foundation authority can operate
*
* @dev Emits `NftDeposit`.
*/
function nftDeposit(uint256 count) external payable;
/**
* @notice Called by BluwhaleNft contract when users redeem nft.
* @notice eth will pay back to user or exchange for Bluwhale to pay back (exchange with the foundation)
* @notice The exchange rate between Bluwhale and eth will be obtained from chainlink
*
* @dev Emits `NftWithdraw`.
*
* @param withBluwhale: whether to pay back with Bluwhale (if not, use eth).
*/
function nftWithdraw(bool withBluwhale) external returns (uint256 amount);
/**
* @notice Deposit tee staked Bluwhale to Vault contract (convert to veBluwhale).
* @notice Only tee authority can operate
*
* @dev Emits `TeeDeposit`.
*/
function teeDeposit(uint256 amount) external;
/**
* @notice Called by ProtocolService contract when tee unstakes or verifier claims tee rewards.
* @notice transfer veBluwhale to receiver.
*
* @dev Emits `TeeWithdraw`.
*
* @param receiver: address who to receive veBluwhale.
* @param amount: amount of veBluwhale transferred to receiver.
*/
function teeWithdraw(address receiver, uint256 amount) external;
/**
* @notice Rewards account initialization, only foundation authority can operate
* @notice Deposit all veBluwhale(Bluwhale -> veBluwhale) for verification rewards
* @notice Define token release rules
*
* @dev Emits `RewardsInit`.
*/
function rewardsInit() external;
/**
* @notice Called by ServiceProtocol contract, used to issue rewards to nodes or NFT holders.
* @notice Strictly follow the release rules and do not release beyond the rules.
*
* @dev Emits `RewardsWithdraw`.
*
* @param receiver: address to receive rewards
* @param amount: amount of rewards
*/
function rewardsWithdraw(address receiver, uint256 amount) external;
/**
* @notice Change the address of foundation.
* @notice can only be operated by foundation authority
*
* @dev Emits `ChangeFoundation`.
*
* @param newFoundation: address of new foundation.
*/
function changeFoundation(address newFoundation) external;
/**
* @notice Change the address of aggregator.
* @notice can only be operated by foundation authority
*
* @dev Emits `UpdateAggregator`.
*
* @param BluwhaleAggregator_: address of aggregator(Bluwhale/eth).
*/
function updateAggregatorAddress(address BluwhaleAggregator_) external;
function oracle(uint256 ethAmount) external view returns (uint256 BluwhaleAmount);
}