Skip to content

Commit

Permalink
Natspec documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernandes committed Sep 10, 2024
1 parent 5dfd26e commit 6f127cb
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 9 deletions.
59 changes: 59 additions & 0 deletions src/Answer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import {IERC20} from
import {ICrossChainMessages} from "./interfaces/ICrossChainMessages.sol";
import {ITiers} from "./interfaces/ITiers.sol";

/**
* @title Answer
* @notice The contract interacts with the `ITiers` interface to retrieve tier information and then sends a response back to the
* originating chain using Chainlink CCIP.
* @dev This contract acts as a receiver on the Base Chain and handles incoming cross-chain messages requesting tier information
* for a wallet address.
*/
contract Answer is CCIPReceiver {
bytes32 private lastReceivedMessageId;
address private lastReceivedWallet;
Expand All @@ -18,12 +25,28 @@ contract Answer is CCIPReceiver {
IRouterClient private router;
IERC20 private linkToken;

/**
* @dev Constructor initializes the contract with addresses for the router, tier data source, and Link token.
* @param _router The address of the `IRouterClient` contract.
* @param _samuraiTiers The address of the contract implementing the `ITiers` interface.
* @param _link The address of the Link token contract.
*/
constructor(address _router, address _samuraiTiers, address _link) CCIPReceiver(_router) {
router = IRouterClient(_router);
samuraiTiers = ITiers(_samuraiTiers);
linkToken = IERC20(_link);
}

/**
* @notice Callback function that handles incoming cross-chain messages and retrieves tier information.
* @dev This function is automatically called by the `CCIPReceiver` contract when a message is received.
* - Stores the message ID and wallet address from the message.
* - Emits an `ICrossChainMessages.MessageReceived` event with details about the received message.
* - Fetches tier information for the received wallet address using the `ITiers` interface.
* - Stores the retrieved tier name.
* - Calls `answerTier` to send a response message containing the tier name.
* @param any2EvmMessage The received cross-chain message containing the wallet address.
*/
function _ccipReceive(Client.Any2EVMMessage memory any2EvmMessage) internal override {
lastReceivedMessageId = any2EvmMessage.messageId;
lastReceivedWallet = abi.decode(any2EvmMessage.data, (address));
Expand All @@ -44,6 +67,11 @@ contract Answer is CCIPReceiver {
answerTier(any2EvmMessage.sourceChainSelector, receiver, lastReceivedWallet, tier.name);
}

/**
* @notice Retrieves details about the last received message.
* @dev This function is a view function and does not modify contract state.
* return A tuple containing the message ID, wallet address, and retrieved tier name (if any).
*/
function getLastReceivedMessageDetails()
external
view
Expand All @@ -52,6 +80,15 @@ contract Answer is CCIPReceiver {
return (lastReceivedMessageId, lastReceivedWallet, lastAnswer);
}

/**
* @notice Calculates and returns the estimated fee for sending a cross-chain message containing the tier response.
* @dev This function is a view function and does not modify contract state.
* @param destinationChainSelector The chain selector of the destination chain.
* @param receiver The address of the contract on the destination chain that will receive the message.
* @param wallet The wallet address for which tier information was requested.
* @param tierName The tier name retrieved for the wallet.
* @return The estimated fee in tokens for sending the message.
*/
function previewFees(uint64 destinationChainSelector, address receiver, address wallet, string memory tierName)
public
view
Expand All @@ -61,6 +98,20 @@ contract Answer is CCIPReceiver {
return router.getFee(destinationChainSelector, evm2AnyMessage);
}

/**
* @notice Sends a cross-chain message containing the tier response to the original sender.
* @dev This function performs the following actions:
* - Calls `previewFees` to estimate the fee.
* - Checks if the contract has sufficient Link tokens for the fee.
* - Approves the Link token for the router to spend the required amount.
* - Sends the cross-chain message using `ccipSend` on the `IRouterClient`.
* - Emits an `ICrossChainMessages.MessageSent` event with details about the message.
* @param destinationChainSelector The chain selector of the destination chain.
* @param receiver The address of the contract on the destination chain that will receive the message.
* @param wallet The wallet address for which tier information was requested.
* @param tierName The tier name retrieved for the wallet.
* @return messageId The message ID generated by the `IRouterClient` for tracking the message.
*/
function answerTier(uint64 destinationChainSelector, address receiver, address wallet, string memory tierName)
public
returns (bytes32 messageId)
Expand All @@ -83,6 +134,14 @@ contract Answer is CCIPReceiver {
return messageId;
}

/**
* @notice Constructs an `EVM2AnyMessage` structure for sending cross-chain messages containing the tier response.
* @dev This function encodes the receiver address, wallet address, and tier name into the message data.
* @param receiver The address of the contract on the destination chain that will receive the message.
* @param wallet The wallet address for which tier information was requested.
* @param tierName The tier name retrieved for the wallet.
* @return evm2AnyMessage The constructed `EVM2AnyMessage` structure.
*/
function mountMessage(address receiver, address wallet, string memory tierName)
private
view
Expand Down
43 changes: 43 additions & 0 deletions src/Ask.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,34 @@ import {IERC20} from
import {ICrossChainMessages} from "./interfaces/ICrossChainMessages.sol";
import {console} from "forge-std/Test.sol";

/**
* @title Ask
* @notice The contract acts as a sender on the Optimism chain and interacts with the `IRouterClient` to send cross-chain messages.
* @dev This contract facilitates sending a wallet address to the Base Chain to retrieve tier information using Chainlink CCIP.
*/
contract Ask is CCIPReceiver {
IRouterClient private router;
IERC20 private linkToken;
mapping(address wallet => string name) public tiers;

/**
* @dev Constructor initializes the contract with the router address and Link token address.
* @param _router The address of the `IRouterClient` contract.
* @param _link The address of the Link token contract.
*/
constructor(address _router, address _link) CCIPReceiver(_router) {
router = IRouterClient(_router);
linkToken = IERC20(_link);
}

/**
* @notice Calculates and returns the estimated fee for sending a cross-chain message to retrieve tier information.
* @dev This function is a view function and does not modify contract state.
* @param destinationChainSelector The chain selector of the destination chain.
* @param receiver The address of the contract on the destination chain that will receive the message.
* @param wallet The wallet address for which tier information is requested.
* @return The estimated fee in tokens for sending the message.
*/
function previewFees(uint64 destinationChainSelector, address receiver, address wallet)
public
view
Expand All @@ -28,6 +46,19 @@ contract Ask is CCIPReceiver {
return router.getFee(destinationChainSelector, evm2AnyMessage);
}

/**
* @notice Initiates the process of sending a cross-chain message to retrieve tier information for a wallet.
* @dev This function performs the following actions:
* - Calls `previewFees` to estimate the fee.
* - Checks if the contract has sufficient Link tokens for the fee.
* - Approves the Link token for the router to spend the required amount.
* - Sends the cross-chain message using `ccipSend` on the `IRouterClient`.
* - Emits an event `MessageSent` with details about the message.
* @param destinationChainSelector The chain selector of the destination chain.
* @param receiver The address of the contract on the destination chain that will receive the message.
* @param wallet The wallet address for which tier information is requested.
* @return messageId The message ID generated by the `IRouterClient` for tracking the message.
*/
function askTier(uint64 destinationChainSelector, address receiver, address wallet)
external
returns (bytes32 messageId)
Expand All @@ -49,12 +80,24 @@ contract Ask is CCIPReceiver {
return messageId;
}

/**
* @notice Callback function that handles incoming cross-chain messages and updates tier information.
* @dev This function is automatically called by the `CCIPReceiver` contract when a message is received.
* @param any2EvmMessage The received cross-chain message containing the wallet address and tier name.
*/
function _ccipReceive(Client.Any2EVMMessage memory any2EvmMessage) internal override {
(address wallet, string memory tierName) = abi.decode(any2EvmMessage.data, (address, string));

tiers[wallet] = tierName;
}

/**
* @notice Constructs an `EVM2AnyMessage` structure for sending cross-chain messages.
* @dev This function encodes the receiver address and wallet address into the message data.
* @param receiver The address of the contract on the destination chain that will receive the message.
* @param wallet The wallet address for which tier information is requested.
* @return evm2AnyMessage The constructed `EVM2AnyMessage` structure.
*/
function mountMessage(address receiver, address wallet) private view returns (Client.EVM2AnyMessage memory) {
Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({
receiver: abi.encode(receiver),
Expand Down
11 changes: 11 additions & 0 deletions src/Points.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;

/**
* @title Points
* @notice It provides a function to grant points to a specific wallet.
* @dev This contract manages points for wallets.
*/
contract Points {
mapping(address wallet => uint256 walletPoints) public walletsPoints;

/**
* @notice Grants a specified amount of points to a wallet.
* @dev Only the contract owner can grant points.
* @param wallet The address of the wallet to grant points to.
* @param points The amount of points to grant.
*/
function grantPoints(address wallet, uint256 points) external {
walletsPoints[wallet] = points;
}
Expand Down
29 changes: 20 additions & 9 deletions src/Tiers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,32 @@ pragma solidity 0.8.27;
import {ITiers} from "./interfaces/ITiers.sol";
import {IPoints} from "./interfaces/IPoints.sol";

/**
* @title Tiers
* @notice It provides functions to add new tiers, retrieve a tier based on a wallet's points,
* and get tier information by its name.
* @dev This contract manages tiers based on wallet points.
*/
contract Tiers {
IPoints iPoints;
uint256 public counter;

mapping(uint256 index => ITiers.Tier tier) public tiers;

/**
* @dev Constructor initializes the contract with the `Points` contract address.
* @param _points The address of the `Points` contract.
*/
constructor(address _points) {
iPoints = IPoints(_points);
}

/**
* @notice Adds a new tier.
* @param name: tier name.
* @param min: min amount to be part of tier.
* @param max: max amount to be part of tier.
* @notice Adds a new tier to the contract.
* @dev Only the contract owner can add new tiers.
* @param name The name of the new tier.
* @param min The minimum points required to be part of the tier.
* @param max The maximum points allowed for the tier.
*/
function addTier(string memory name, uint256 min, uint256 max) external {
uint256 index = counter + 1;
Expand All @@ -27,9 +38,9 @@ contract Tiers {
}

/**
* @notice Gets the tier a wallet belongs to based on Sam NFT holdings, lockups, and LP staking.
* @param wallet: Address of the wallet to check.
* @return tier: The tier information for the wallet.
* @notice Gets the tier a wallet belongs to based on its points.
* @param wallet The address of the wallet to check.
* @return The tier information for the wallet.
*/
function getTier(address wallet) public view returns (ITiers.Tier memory) {
// Get wallet points
Expand All @@ -50,8 +61,8 @@ contract Tiers {

/**
* @notice Gets the tier information by its name.
* @param name: Name of the tier to get.
* @return tier: The tier information matching the name.
* @param name The name of the tier to get.
* @return The tier information matching the name.
*/
function getTierByName(string memory name) public view returns (ITiers.Tier memory) {
bytes32 nameHash = keccak256(abi.encodePacked(name));
Expand Down

0 comments on commit 6f127cb

Please sign in to comment.