# Bluwhale Protocol Service

### Bluwhale Protocol Service

* Utilizes a proxy contract.
* Manages system parameters separately through the Settings contract.
* Does not store funds; all funds are managed by the Vault contract. This contract only has operational authority for fixed roles.
* Inherits from AccessControlUpgradeable and VRFConsumerBaseV2 (for generating random numbers using Chainlink).
* Implements the main logic of the Bluwhale protocol.

#### Core Function Explanations

[Trusted Execution Environment (TEE)](https://docs.carv.io/carv-protocol/verifier-node-explained/how-do-verifier-nodes-work/trusted-execution-environment-tee)

[Verifier Node](https://docs.carv.io/carv-protocol/verifier-node-explained/how-do-verifier-nodes-work/verifier-node)

[Attestation](https://docs.carv.io/carv-protocol/verifier-node-explained/how-do-verifier-nodes-work/attestation)

[Delegation](https://docs.carv.io/carv-protocol/verifier-node-explained/delegation)

[Rewards](https://docs.carv.io/carv-protocol/verifier-node-explained/how-do-verifier-nodes-work/rewards)

Function Definitions & Explanations

Copy

// SPDX-License-Identifier: GPL-3.0

\


pragma solidity ^0.8.20;

\
\
\


interface IProtocolService {

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice This enum represents result of an attestation reported by verifier

\


&#x20;   \*

\


&#x20;   \* \`Valid\`: This attestation can be parsed successfully and is not malicious

\


&#x20;   \* \`Invalid\`: This attestation cannot be parsed successfully

\


&#x20;   \* \`Malicious\`: This attestation can be parsed successfully but is malicious

\


&#x20;   \*/

\


&#x20;  enum AttestationResult {

\


&#x20;      Valid,

\


&#x20;      Invalid,

\


&#x20;      Malicious

\


&#x20;  }

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice This struct represents information of a node

\


&#x20;   \*

\


&#x20;   \* \`id\`: The globally unique ID of the node. The node is automatically registered when

\


&#x20;   \*        it calls \`nodeEnter\` for the first time. Up to 65535 nodes can be registered.

\


&#x20;   \* \`listIndex\`: The position of the node in the current \`activeVrfNodeList\`

\


&#x20;   \* \`active\`: Is the node active?

\


&#x20;   \* \`lastConfirmDate\`: The date on which reward was last confirmed.

\


&#x20;   \* \`missedVerifyCount\`: The number of verifications the node currently misses

\


&#x20;   \* \`selfTotalRewards\`: The total rewards of the node itself

\


&#x20;   \* \`selfClaimedRewards\`: The rewards claimed by the node itself

\


&#x20;   \* \`delegationRewards\`: The rewards of the node’s delegator

\


&#x20;   \* \`lastEnterTime\`: The time when the node last called \`nodeEnter\` to go online

\


&#x20;   \* \`commissionRate\`: rate of commission, which is given by NFT holders to the verifier node.(decimals: 4)

\


&#x20;   \* \`commissionRateLastModifyAt\`: timestamp of last modifying commission rate

\


&#x20;   \*/

\


&#x20;  struct NodeInfo {

\


&#x20;      uint16 id;

\


&#x20;      uint16 listIndex;

\


&#x20;      bool active;

\


&#x20;      uint32 lastConfirmDate;

\


&#x20;      uint64 missedVerifyCount;

\


&#x20;      int256 selfTotalRewards;

\


&#x20;      uint256 selfClaimedRewards;

\


&#x20;      uint256 delegationRewards;

\


&#x20;      uint256 lastEnterTime;

\


&#x20;      address claimer;

\


&#x20;      uint32 commissionRate; // decimals: 4

\


&#x20;      uint256 commissionRateLastModifyAt;

\


&#x20;  }

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice This struct represents reward information of a BluwhaleNft token

\


&#x20;   \*

\


&#x20;   \* \`initialRewards\`: When this tokenID is delegated to a node, the initial amount of delegator's rewards needs to be recorded.

\


&#x20;   \* \`totalRewards\`: The amount of rewards this tokenID has been confirmed

\


&#x20;   \* \`claimedRewards\`: The amount of rewards this tokenID has been claimed

\


&#x20;   \*/

\


&#x20;  struct TokenRewardInfo {

\


&#x20;      uint256 initialRewards;

\


&#x20;      uint256 totalRewards;

\


&#x20;      uint256 claimedRewards;

\


&#x20;  }

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice This struct represents staking information of a tee

\


&#x20;   \*

\


&#x20;   \* \`valid\`: Whether tee is currently valid, invalid tee cannot report attestation

\


&#x20;   \* \`staked\`: tee’s current staked amount

\


&#x20;   \* \`lastReportAt\`: The time when tee last reported attestation, used for unstake check

\


&#x20;   \*/

\


&#x20;  struct TeeStakeInfo {

\


&#x20;      bool valid;

\


&#x20;      uint256 staked;

\


&#x20;      uint256 lastReportAt;

\


&#x20;  }

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice This struct represents information of an attestation

\


&#x20;   \*

\


&#x20;   \* \`reporter\`: The address of the tee who reported this attestation

\


&#x20;   \* \`valid\`: The number of votes that this attestation is considered valid (voted by the verifier node)

\


&#x20;   \* \`invalid\`: The number of votes that this attestation is considered invalid (voted by the verifier node)

\


&#x20;   \* \`vrfChosenID\`: ID of the currently randomly selected verification nodes

\


&#x20;   \* \`slashed\`: Has this attestation been slashed?

\


&#x20;   \* \`deadline\`: Deadline for collecting verification

\


&#x20;   \*/

\


&#x20;  struct Attestation {

\


&#x20;      address reporter;

\


&#x20;      uint16 valid;

\


&#x20;      uint16 invalid;

\


&#x20;      uint16 malicious;

\


&#x20;      uint32 vrfChosenID;

\


&#x20;      bool slashed;

\


&#x20;      uint256 deadline;

\


&#x20;  }

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice This struct represents information of an verification with signature

\


&#x20;   \*

\


&#x20;   \* \`result\`: result of this attestation

\


&#x20;   \* \`index\`: index of this node in activeVrfNodeList

\


&#x20;   \* \`signer\`: address of this node (sign the Data to call contract gasless)

\


&#x20;   \* \`v\`: v of signature signed by signer

\


&#x20;   \* \`r\`: r of signature signed by signer

\


&#x20;   \* \`s\`: s of signature signed by signer

\


&#x20;   \*/

\


&#x20;  struct VerificationInfo {

\


&#x20;      AttestationResult result;

\


&#x20;      uint16 index;

\


&#x20;      address signer;

\


&#x20;      uint8 v;

\


&#x20;      bytes32 r;

\


&#x20;      bytes32 s;

\


&#x20;  }

\
\
\


&#x20;  // admin

\


&#x20;  event UpdateVrfAddress(address vrf);

\


&#x20;  event UpdateSettingsAddress(address settings);

\
\
\


&#x20;  // tee

\


&#x20;  event TeeStake(address tee, uint256 amount);

\


&#x20;  event TeeUnstake(address tee, uint256 amount);

\


&#x20;  event TeeSlash(address tee, bytes32 attestationID, uint256 amount);

\


&#x20;  event ClaimMaliciousTeeRewards(address verifer, uint256 amount);

\


&#x20;  event TeeReportAttestations(address tee, bytes32\[] attestationIDs, string\[] attestationInfos, uint256 requestID);

\


&#x20;  event ConfirmVrfNodes(uint256 requestId, uint16\[] vrfChosen, uint256 deadline);

\
\
\


&#x20;  // node

\


&#x20;  event NodeRegister(address node, uint16 id);

\


&#x20;  event NodeActivate(address node);

\


&#x20;  event NodeClear(address node);

\


&#x20;  event NodeSlash(address node, bytes32 attestationID, uint256 rewards);

\


&#x20;  event NodeModifyCommissionRate(address node, uint32 commissionRate);

\


&#x20;  event NodeSetClaimer(address node, address claimer);

\


&#x20;  event NodeClaim(address node, address claimer, uint256 rewards);

\


&#x20;  event NodeReportVerification(address node, bytes32 attestationID, AttestationResult result);

\


&#x20;  event NodeReportVerificationBatch(bytes32 attestationID, VerificationInfo\[] infos);

\
\
\


&#x20;  // delegation

\


&#x20;  event Delegate(uint256 tokenID, address to);

\


&#x20;  event Redelegate(uint256 tokenID, address to);

\


&#x20;  event Undelegate(uint256 tokenID, address to);

\


&#x20;  event ClaimRewards(uint256 tokenID, uint256 rewards);

\
\
\


&#x20;  /\*----------------------------------------------------------------------------------------------------------------\*/

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice update address of Settings contract.

\


&#x20;   \*

\


&#x20;   \* @dev Only admin role.

\


&#x20;   \* @dev Emits \`UpdateSettingsAddress\`.

\


&#x20;   \*

\


&#x20;   \* @param settings\_: address of Settings contract.

\


&#x20;   \*/

\


&#x20;  function updateSettingsAddress(address settings\_) external;

\


&#x20;  /\*\*

\


&#x20;   \* @notice update address of BluwhaleVrf contract.

\


&#x20;   \*

\


&#x20;   \* @dev Only admin role.

\


&#x20;   \* @dev Emits \`UpdateVrfAddress\`.

\


&#x20;   \*

\


&#x20;   \* @param BluwhaleVrf\_: address of BluwhaleVrf contract.

\


&#x20;   \*/

\


&#x20;  function updateVrfAddress(address BluwhaleVrf\_) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Tee needs to stake Bluwhales before reporting attestation,

\


&#x20;   \* @notice and Bluwhales will be converted to veBluwhales stored in Vault.

\


&#x20;   \* @notice which will be used to slash when tee proven to be evil.

\


&#x20;   \*

\


&#x20;   \* @dev Only tee role (granted by admin role).

\


&#x20;   \* @dev Emits \`TeeStake\`.

\


&#x20;   \*

\


&#x20;   \* @param amount: amount of Bluwhale tee plans to stake.

\


&#x20;   \*/

\


&#x20;  function teeStake(uint256 amount) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Tee withdraws staked veBluwhales, rules are as follows:

\


&#x20;   \* @notice 1. enough time has passed since the last attestation was submitted.

\


&#x20;   \* @notice 2. veBluwhales that have been slashed cannot be unstaked.

\


&#x20;   \* @notice 3. unable to continue reporting attestation after unstaking.

\


&#x20;   \*

\


&#x20;   \* @dev Only tee role (granted by admin role).

\


&#x20;   \* @dev Emits \`TeeUnstake\`.

\


&#x20;   \*/

\


&#x20;  function teeUnstake() external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice When the attestation reported by a tee is proven to be malicious,

\


&#x20;   \* @notice anyone can initiate a teeSlash, which will slash the veBluwhales staked by the tee.

\


&#x20;   \* @notice Each malicious attestation can only be slashed once.

\


&#x20;   \* @notice When the veBluwhales staked by a tee are slashed below a threshold,

\


&#x20;   \* @notice the tee will be forcibly restricted from continuing to report attestation.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`TeeSlash\`.

\


&#x20;   \*

\


&#x20;   \* @param attestationID: id of attestation which is proven malicious.

\


&#x20;   \*/

\


&#x20;  function teeSlash(bytes32 attestationID) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice When an attestation reported by a tee is slashed,

\


&#x20;   \* @notice verifiers that have reported verification for this attestation can claim the reward.

\


&#x20;   \* @notice If a verifier have not reported verification of this attestation, it cannot claim the reward.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`ClaimMaliciousTeeRewards\`.

\


&#x20;   \*

\


&#x20;   \* @param attestationID: id of attestation which is slashed.

\


&#x20;   \*/

\


&#x20;  function claimMaliciousTeeRewards(bytes32 attestationID) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Tee reports attestations. The same attestation can only be reported once.

\


&#x20;   \*

\


&#x20;   \* @dev Only staked tee role.

\


&#x20;   \* @dev Emits \`TeeReportAttestations\`.

\


&#x20;   \* @dev A request to apply for VRF will be sent to chainlink.

\


&#x20;   \* @dev After receiving the callback from chainlink, emits \`ConfirmVrfNodes\`.

\


&#x20;   \*

\


&#x20;   \* @param attestationInfos: attestations to be reported.

\


&#x20;   \*/

\


&#x20;  function teeReportAttestations(string\[] memory attestationInfos) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice In order to save costs more efficiently when selecting nodes in VRF,

\


&#x20;   \* @notice we designed a data structure \`activeVrfNodeList\` for this purpose.

\


&#x20;   \* @notice \`activeVrfNodeList\` stores up to 2000 active nodes with delegation weight,

\


&#x20;   \* @notice and each time VRF will select from these nodes.

\


&#x20;   \*

\


&#x20;   \* @notice Nodes need to activate themselves by calling nodeEnter of the smart contract

\


&#x20;   \* @notice To successfully activate a node, caller need to meet the following conditions:

\


&#x20;   \* @notice 1. The caller needs to hold BluwhaleNft, or be delegated by other holders

\


&#x20;   \* @notice 2. If the current \`activeVrfNodeList\` is full, you need to choose a node

\


&#x20;   \* @notice    in the list with less delegation weight than yourself to replace it.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`NodeActivate\`.

\


&#x20;   \* @dev If any node is kicked and replaced by your node. Emits \`NodeClear\`.

\


&#x20;   \* @dev If any node calls nodeEnter for the first time. Emits \`NodeRegister\`.

\


&#x20;   \*

\


&#x20;   \* @param replacedNode: address of the node that needs to be replaced by your node

\


&#x20;   \*                  only works when the \`activeVrfNodeList\` is full

\


&#x20;   \*/

\


&#x20;  function nodeEnter(address replacedNode) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Exits by node itself, and verification cannot be reported after exiting.

\


&#x20;   \* @notice When a node exits, it will be punished based on missing counts during the online period.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`NodeClear\`.

\


&#x20;   \*/

\


&#x20;  function nodeExit() external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Modify the commission rate of verifier node

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`NodeModifyCommissionRate\`.

\


&#x20;   \*

\


&#x20;   \* @param commissionRate: rate of commission, which is given by NFT holders to the verifier node

\


&#x20;   \*/

\


&#x20;  function nodeModifyCommissionRate(uint32 commissionRate) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Similar to \`nodeEnter\`,

\


&#x20;   \* @notice but the txn can be broadcast to the chain by other address after being authenticated by the node.

\


&#x20;   \* @notice Compared with the \`nodeEnter\`, it is gasless for the verifier node.

\


&#x20;   \* @notice following the eip-712.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`NodeActivate\`.

\


&#x20;   \* @dev If any node is kicked and replaced by your node. Emits \`NodeClear\`.

\


&#x20;   \* @dev If any node calls nodeEnter for the first time. Emits \`NodeRegister\`.

\


&#x20;   \*

\


&#x20;   \* @param replacedNode: address of the node that needs to be replaced by your node

\


&#x20;   \*                  only works when the \`activeVrfNodeList\` is full

\


&#x20;   \* @param expiredAt: transaction expiration time

\


&#x20;   \* @param signer: address of verifier node ready to enter

\


&#x20;   \*/

\


&#x20;  function nodeEnterWithSignature(

\


&#x20;      address replacedNode, uint256 expiredAt, address signer, uint8 v, bytes32 r, bytes32 s

\


&#x20;  ) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Similar to \`nodeExit\`,

\


&#x20;   \* @notice but the txn can be broadcast to the chain by other address after being authenticated by the node.

\


&#x20;   \* @notice Compared with the \`nodeExit\`, it is gasless for the verifier node.

\


&#x20;   \* @notice following the eip-712.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`NodeClear\`.

\


&#x20;   \*

\


&#x20;   \* @param expiredAt: transaction expiration time

\


&#x20;   \* @param signer: address of verifier node ready to exit

\


&#x20;   \*/

\


&#x20;  function nodeExitWithSignature(

\


&#x20;      uint256 expiredAt, address signer, uint8 v, bytes32 r, bytes32 s

\


&#x20;  ) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Similar to \`nodeModifyCommissionRate\`,

\


&#x20;   \* @notice but the txn can be broadcast to the chain by other address after being authenticated by the node.

\


&#x20;   \* @notice Compared with the \`nodeModifyCommissionRate\`, it is gasless for the verifier node.

\


&#x20;   \* @notice following the eip-712.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`NodeModifyCommissionRate\`.

\


&#x20;   \*

\


&#x20;   \* @param commissionRate: rate of commission, which is given by NFT holders to the verifier node

\


&#x20;   \* @param expiredAt: transaction expiration time

\


&#x20;   \* @param signer: address of verifier node

\


&#x20;   \*/

\


&#x20;  function nodeModifyCommissionRateWithSignature(

\


&#x20;      uint32 commissionRate, uint256 expiredAt, address signer, uint8 v, bytes32 r, bytes32 s

\


&#x20;  ) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Specify the address that can claim rewards of this verifier node

\


&#x20;   \* @notice it is gasless for the verifier node.

\


&#x20;   \* @notice following the eip-712.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`NodeSetClaimer\`.

\


&#x20;   \*

\


&#x20;   \* @param claimer: address of whom can claim reward of this verifier

\


&#x20;   \* @param expiredAt: transaction expiration time

\


&#x20;   \* @param signer: address of verifier node

\


&#x20;   \*/

\


&#x20;  function nodeSetRewardClaimerWithSignature(

\


&#x20;      address claimer, uint256 expiredAt, address signer, uint8 v, bytes32 r, bytes32 s

\


&#x20;  ) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Claim reward of node.

\


&#x20;   \* @notice The reward for reporting verifications is divided into two parts: node's reward and delegators' reward

\


&#x20;   \* @notice Only when the node is online for more than 6 hours/day will there be reward.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`NodeClaim\`.

\


&#x20;   \*

\


&#x20;   \* @param node: address of node to claim reward

\


&#x20;   \*/

\


&#x20;  function nodeClaim(address node) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Anyone can initiate a slash for a miss reporting of a node.

\


&#x20;   \* @notice Each miss reporting of a node can only be slashed once.

\


&#x20;   \* @notice When a node is selected by VRF but fails to report a verification within the specified time,

\


&#x20;   \* @notice the node can be slashed.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`NodeSlash\`.

\


&#x20;   \*

\


&#x20;   \* @param node: address of node to be slashed

\


&#x20;   \* @param attestationID: id of attestation that node miss reporting

\


&#x20;   \* @param index: index of this node in vrfChosen list of this attestation

\


&#x20;   \*/

\


&#x20;  function nodeSlash(address node, bytes32 attestationID, uint16 index) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice If the node is online but hasn't reported verification that day,

\


&#x20;   \* @notice the smart contract needs to be notified through this function to update the status of the node today.

\


&#x20;   \*

\


&#x20;   \* @param node: address of the node to report daily active

\


&#x20;   \*/

\


&#x20;  function nodeReportDailyActive(address node) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice After an attestation is reported, a group of nodes will be randomly selected through chainlink's VRF.

\


&#x20;   \* @notice These nodes need to submit the verification within the specified time.

\


&#x20;   \* @notice When a node is selected by VRF, the proof is submitted by calling \`nodeReportVerification\`.

\


&#x20;   \* @notice The verification cannot be submitted repeatedly.

\


&#x20;   \*

\


&#x20;   \* @dev Only nodes chosen by VRF in this attestation.

\


&#x20;   \* @dev Emits \`NodeReportVerification\`.

\


&#x20;   \*

\


&#x20;   \* @param attestationID: id of attestation

\


&#x20;   \* @param index: index of this node in vrfChosen list of this attestation

\


&#x20;   \* @param result: Whether the attestation is valid after being checked by the node.

\


&#x20;   \*/

\


&#x20;  function nodeReportVerification(bytes32 attestationID, uint16 index, AttestationResult result) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Batch reporting verification.

\


&#x20;   \* @notice One address can collect multiple verifications and delegate reporting them in batches,

\


&#x20;   \* @notice following the eip-712.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`NodeReportVerificationBatch\`.

\


&#x20;   \*/

\


&#x20;  function nodeReportVerificationBatch(bytes32 attestationID, VerificationInfo\[] calldata infos) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice If the NFT holder doesn't want to run the node to report the verification himself,

\


&#x20;   \* @notice he can delegate the authority to others to run by calling \`delegate\`.

\


&#x20;   \* @notice After delegating, NFT holders will give a proportion of rewards (10%) to the delegatee.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`Delegate\`.

\


&#x20;   \*

\


&#x20;   \* @param tokenID: tokenID of BluwhaleNft to be delegated.

\


&#x20;   \* @param to: address of whom you want to delegate to

\


&#x20;   \*/

\


&#x20;  function delegate(uint256 tokenID, address to) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Specify a new delegatee to replace the current delegatee.

\


&#x20;   \* @notice During the \`redelegate\`, the node may be triggered to exit.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`Redelegate\`.

\


&#x20;   \* @dev When the node's delegation weight is reduced to 0, it will be forced offline. Emits \`NodeClear\`

\


&#x20;   \*

\


&#x20;   \* @param tokenID: tokenID of BluwhaleNft to be redelegated.

\


&#x20;   \* @param to: address of whom you want to redelegate to

\


&#x20;   \*/

\


&#x20;  function redelegate(uint256 tokenID, address to) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Cancel current delegation.

\


&#x20;   \* @notice During the \`undelegate\`, the node may be triggered to exit.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`undelegate\`.

\


&#x20;   \* @dev When the node's delegation weight is reduced to 0, it will be forced offline. Emits \`NodeClear\`

\


&#x20;   \*

\


&#x20;   \* @param tokenID: tokenID of BluwhaleNft to be undelegated.

\


&#x20;   \*/

\


&#x20;  function undelegate(uint256 tokenID) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Claim rewards corresponding to a certain tokenID owned by you.

\


&#x20;   \* @notice vault.rewardsWithdraw() will be called to transfer veBluwhale to the user.

\


&#x20;   \* @notice After the user claim the reward, this BluwhaleNft cannot be redeemed.

\


&#x20;   \*

\


&#x20;   \* @dev Emits \`ClaimRewards\`.

\


&#x20;   \*

\


&#x20;   \* @param tokenID: The token ID that needs to be claimed rewards

\


&#x20;   \*/

\


&#x20;  function claimRewards(uint256 tokenID) external;

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Check whether this tokenID has already claimed rewards.

\


&#x20;   \*

\


&#x20;   \* @param tokenID: token ID

\


&#x20;   \* @return claimed: whether this tokenID has already claimed rewards

\


&#x20;   \*/

\


&#x20;  function checkClaimed(uint256 tokenID) external view returns (bool);

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Get the index of today.

\


&#x20;   \*/

\


&#x20;  function todayIndex() external view returns (uint32);

\
\
\


&#x20;  /\*\*

\


&#x20;   \* @notice Get the offset of today.

\


&#x20;   \*/

\


&#x20;  function todayOffset() external view returns (uint256);

\


}

\
