From 6edfd9d364d6932634cd883870211041fc8f4cee Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Mon, 15 Jul 2024 15:40:58 +0200 Subject: [PATCH] generate api reference --- api_reference/ccip/BurnMintERC677Helper.mdx | 41 +++ api_reference/ccip/CCIPLocalSimulator.mdx | 167 +++++++++++ api_reference/ccip/CCIPLocalSimulatorFork.mdx | 164 +++++++++++ api_reference/ccip/MockEvm2EvmOffRamp.mdx | 175 ++++++++++++ api_reference/ccip/Register.mdx | 72 +++++ api_reference/ccip/index.mdx | 7 + .../data-feeds/MockOffchainAggregator.mdx | 175 ++++++++++++ api_reference/data-feeds/MockV3Aggregator.mdx | 262 ++++++++++++++++++ api_reference/data-feeds/index.mdx | 5 + .../interfaces/AggregatorInterface.mdx | 122 ++++++++ .../interfaces/AggregatorV2V3Interface.mdx | 6 + .../interfaces/AggregatorV3Interface.mdx | 96 +++++++ api_reference/data-feeds/interfaces/index.mdx | 5 + api_reference/index.mdx | 5 + api_reference/shared/LinkToken.mdx | 29 ++ api_reference/shared/WETH9.mdx | 106 +++++++ api_reference/shared/index.mdx | 4 + generate-index-files.ts | 54 ++++ hardhat.config.ts | 14 +- package-lock.json | 182 +++++++++--- package.json | 10 +- src/ccip/BurnMintERC677Helper.sol | 15 +- src/ccip/CCIPLocalSimulator.sol | 17 ++ src/ccip/CCIPLocalSimulatorFork.sol | 79 +++++- src/ccip/MockEvm2EvmOffRamp.sol | 66 ++++- src/ccip/Register.sol | 28 +- src/data-feeds/MockOffchainAggregator.sol | 115 +++++++- src/data-feeds/MockV3Aggregator.sol | 121 +++++++- .../interfaces/AggregatorInterface.sol | 49 +++- .../interfaces/AggregatorV2V3Interface.sol | 9 +- .../interfaces/AggregatorV3Interface.sol | 57 +++- src/shared/LinkToken.sol | 18 +- 32 files changed, 2168 insertions(+), 107 deletions(-) create mode 100644 api_reference/ccip/BurnMintERC677Helper.mdx create mode 100644 api_reference/ccip/CCIPLocalSimulator.mdx create mode 100644 api_reference/ccip/CCIPLocalSimulatorFork.mdx create mode 100644 api_reference/ccip/MockEvm2EvmOffRamp.mdx create mode 100644 api_reference/ccip/Register.mdx create mode 100644 api_reference/ccip/index.mdx create mode 100644 api_reference/data-feeds/MockOffchainAggregator.mdx create mode 100644 api_reference/data-feeds/MockV3Aggregator.mdx create mode 100644 api_reference/data-feeds/index.mdx create mode 100644 api_reference/data-feeds/interfaces/AggregatorInterface.mdx create mode 100644 api_reference/data-feeds/interfaces/AggregatorV2V3Interface.mdx create mode 100644 api_reference/data-feeds/interfaces/AggregatorV3Interface.mdx create mode 100644 api_reference/data-feeds/interfaces/index.mdx create mode 100644 api_reference/index.mdx create mode 100644 api_reference/shared/LinkToken.mdx create mode 100644 api_reference/shared/WETH9.mdx create mode 100644 api_reference/shared/index.mdx create mode 100644 generate-index-files.ts diff --git a/api_reference/ccip/BurnMintERC677Helper.mdx b/api_reference/ccip/BurnMintERC677Helper.mdx new file mode 100644 index 0000000..0f2b619 --- /dev/null +++ b/api_reference/ccip/BurnMintERC677Helper.mdx @@ -0,0 +1,41 @@ +# Solidity API + +## BurnMintERC677Helper + +This contract extends the functionality of the BurnMintERC677 token contract to include a `drip` function that mints one full token to a specified address. + +_Inherits from the BurnMintERC677 contract and sets the token name, symbol, decimals, and initial supply in the constructor._ + +### constructor + +```solidity +constructor(string name, string symbol) public +``` + +Constructor to initialize the BurnMintERC677Helper contract with a name and symbol. + +_Calls the parent constructor of BurnMintERC677 with fixed decimals (18) and initial supply (0)._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| name | string | - The name of the token. | +| symbol | string | - The symbol of the token. | + +### drip + +```solidity +function drip(address to) external +``` + +Mints one full token (1e18) to the specified address. + +_Calls the internal `_mint` function from the BurnMintERC677 contract._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| to | address | - The address to receive the minted token. | + diff --git a/api_reference/ccip/CCIPLocalSimulator.mdx b/api_reference/ccip/CCIPLocalSimulator.mdx new file mode 100644 index 0000000..64c3276 --- /dev/null +++ b/api_reference/ccip/CCIPLocalSimulator.mdx @@ -0,0 +1,167 @@ +# Solidity API + +## CCIPLocalSimulator + +This contract simulates local CCIP (Cross-Chain Interoperability Protocol) operations for testing and development purposes. + +_This contract includes methods to manage supported tokens and configurations for local simulations._ + +### CHAIN_SELECTOR + +```solidity +uint64 CHAIN_SELECTOR +``` + +The unique CCIP Chain Selector constant + +### i_wrappedNative + +```solidity +contract WETH9 i_wrappedNative +``` + +The wrapped native token instance + +### i_linkToken + +```solidity +contract LinkToken i_linkToken +``` + +The LINK token instance + +### i_ccipBnM + +```solidity +contract BurnMintERC677Helper i_ccipBnM +``` + +The BurnMintERC677Helper instance for CCIP-BnM token + +### i_ccipLnM + +```solidity +contract BurnMintERC677Helper i_ccipLnM +``` + +The BurnMintERC677Helper instance for CCIP-LnM token + +### i_mockRouter + +```solidity +contract MockCCIPRouter i_mockRouter +``` + +The mock CCIP router instance + +### s_supportedTokens + +```solidity +address[] s_supportedTokens +``` + +The list of supported token addresses + +### constructor + +```solidity +constructor() public +``` + +Constructor to initialize the contract and pre-deployed token instances + +### supportNewToken + +```solidity +function supportNewToken(address tokenAddress) external +``` + +Allows user to support any new token, besides CCIP BnM and CCIP LnM, for cross-chain transfers. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenAddress | address | - The address of the token to add to the list of supported tokens. | + +### isChainSupported + +```solidity +function isChainSupported(uint64 chainSelector) public pure returns (bool supported) +``` + +Checks whether the provided `chainSelector` is supported by the simulator. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| chainSelector | uint64 | - The unique CCIP Chain Selector. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| supported | bool | - Returns true if `chainSelector` is supported by the simulator. | + +### getSupportedTokens + +```solidity +function getSupportedTokens(uint64 chainSelector) external view returns (address[] tokens) +``` + +Gets a list of token addresses that are supported for cross-chain transfers by the simulator. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| chainSelector | uint64 | - The unique CCIP Chain Selector. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokens | address[] | - Returns a list of token addresses that are supported for cross-chain transfers by the simulator. | + +### requestLinkFromFaucet + +```solidity +function requestLinkFromFaucet(address to, uint256 amount) external returns (bool success) +``` + +Requests LINK tokens from the faucet. The provided amount of tokens are transferred to provided destination address. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| to | address | - The address to which LINK tokens are to be sent. | +| amount | uint256 | - The amount of LINK tokens to send. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| success | bool | - Returns `true` if the transfer of tokens was successful, otherwise `false`. | + +### configuration + +```solidity +function configuration() public view returns (uint64 chainSelector_, contract IRouterClient sourceRouter_, contract IRouterClient destinationRouter_, contract WETH9 wrappedNative_, contract LinkToken linkToken_, contract BurnMintERC677Helper ccipBnM_, contract BurnMintERC677Helper ccipLnM_) +``` + +Returns configuration details for pre-deployed contracts and services needed for local CCIP simulations. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| chainSelector_ | uint64 | - The unique CCIP Chain Selector. | +| sourceRouter_ | contract IRouterClient | - The source chain Router contract. | +| destinationRouter_ | contract IRouterClient | - The destination chain Router contract. | +| wrappedNative_ | contract WETH9 | - The wrapped native token which can be used for CCIP fees. | +| linkToken_ | contract LinkToken | - The LINK token. | +| ccipBnM_ | contract BurnMintERC677Helper | - The ccipBnM token. | +| ccipLnM_ | contract BurnMintERC677Helper | - The ccipLnM token. | + diff --git a/api_reference/ccip/CCIPLocalSimulatorFork.mdx b/api_reference/ccip/CCIPLocalSimulatorFork.mdx new file mode 100644 index 0000000..bb811ca --- /dev/null +++ b/api_reference/ccip/CCIPLocalSimulatorFork.mdx @@ -0,0 +1,164 @@ +# Solidity API + +## IRouterFork + +### OffRamp + +```solidity +struct OffRamp { + uint64 sourceChainSelector; + address offRamp; +} +``` + +### getOffRamps + +```solidity +function getOffRamps() external view returns (struct IRouterFork.OffRamp[]) +``` + +Gets the list of offRamps + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | struct IRouterFork.OffRamp[] | offRamps - Array of OffRamp structs | + +## IEVM2EVMOffRampFork + +### executeSingleMessage + +```solidity +function executeSingleMessage(struct Internal.EVM2EVMMessage message, bytes[] offchainTokenData) external +``` + +Executes a single CCIP message on the offRamp + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| message | struct Internal.EVM2EVMMessage | - The CCIP message to be executed | +| offchainTokenData | bytes[] | - Additional offchain token data | + +## CCIPLocalSimulatorFork + +Works with Foundry only + +### CCIPSendRequested + +```solidity +event CCIPSendRequested(struct Internal.EVM2EVMMessage message) +``` + +Event emitted when a CCIP send request is made + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| message | struct Internal.EVM2EVMMessage | - The EVM2EVM message that was sent | + +### i_register + +```solidity +contract Register i_register +``` + +The immutable register instance + +### LINK_FAUCET + +```solidity +address LINK_FAUCET +``` + +The address of the LINK faucet + +### s_processedMessages + +```solidity +mapping(bytes32 => bool) s_processedMessages +``` + +Mapping to track processed messages + +### constructor + +```solidity +constructor() public +``` + +Constructor to initialize the contract + +### switchChainAndRouteMessage + +```solidity +function switchChainAndRouteMessage(uint256 forkId) external +``` + +To be called after the sending of the cross-chain message (`ccipSend`). Goes through the list of past logs and looks for the `CCIPSendRequested` event. Switches to a destination network fork. Routes the sent cross-chain message on the destination network. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| forkId | uint256 | - The ID of the destination network fork. This is the returned value of `createFork()` or `createSelectFork()` | + +### getNetworkDetails + +```solidity +function getNetworkDetails(uint256 chainId) external view returns (struct Register.NetworkDetails) +``` + +Returns the default values for currently CCIP supported networks. If network is not present or some of the values are changed, user can manually add new network details using the `setNetworkDetails` function. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| chainId | uint256 | - The blockchain network chain ID. For example 11155111 for Ethereum Sepolia. Not CCIP chain selector. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | struct Register.NetworkDetails | networkDetails - The tuple containing: chainSelector - The unique CCIP Chain Selector. routerAddress - The address of the CCIP Router contract. linkAddress - The address of the LINK token. wrappedNativeAddress - The address of the wrapped native token that can be used for CCIP fees. ccipBnMAddress - The address of the CCIP BnM token. ccipLnMAddress - The address of the CCIP LnM token. | + +### setNetworkDetails + +```solidity +function setNetworkDetails(uint256 chainId, struct Register.NetworkDetails networkDetails) external +``` + +If network details are not present or some of the values are changed, user can manually add new network details using the `setNetworkDetails` function. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| chainId | uint256 | - The blockchain network chain ID. For example 11155111 for Ethereum Sepolia. Not CCIP chain selector. | +| networkDetails | struct Register.NetworkDetails | - The tuple containing: chainSelector - The unique CCIP Chain Selector. routerAddress - The address of the CCIP Router contract. linkAddress - The address of the LINK token. wrappedNativeAddress - The address of the wrapped native token that can be used for CCIP fees. ccipBnMAddress - The address of the CCIP BnM token. ccipLnMAddress - The address of the CCIP LnM token. | + +### requestLinkFromFaucet + +```solidity +function requestLinkFromFaucet(address to, uint256 amount) external returns (bool success) +``` + +Requests LINK tokens from the faucet. The provided amount of tokens are transferred to provided destination address. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| to | address | - The address to which LINK tokens are to be sent. | +| amount | uint256 | - The amount of LINK tokens to send. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| success | bool | - Returns `true` if the transfer of tokens was successful, otherwise `false`. | + diff --git a/api_reference/ccip/MockEvm2EvmOffRamp.mdx b/api_reference/ccip/MockEvm2EvmOffRamp.mdx new file mode 100644 index 0000000..3db9a2e --- /dev/null +++ b/api_reference/ccip/MockEvm2EvmOffRamp.mdx @@ -0,0 +1,175 @@ +# Solidity API + +## MockEvm2EvmOffRamp + +This contract handles off-ramp processes for CCIP messages + +### DynamicConfig + +```solidity +struct DynamicConfig { + uint32 permissionLessExecutionThresholdSeconds; + address router; + address priceRegistry; + uint16 maxNumberOfTokensPerMsg; + uint32 maxDataBytes; + uint32 maxPoolReleaseOrMintGas; +} +``` + +### i_sourceChainSelector + +```solidity +uint64 i_sourceChainSelector +``` + +_chain selector for the source chain_ + +### s_ccipLocalSimulator + +```solidity +address s_ccipLocalSimulator +``` + +_Address of the CCIP Local Simulator_ + +### s_dynamicConfig + +```solidity +struct MockEvm2EvmOffRamp.DynamicConfig s_dynamicConfig +``` + +_Dynamic configuration of the offramp_ + +### CanOnlySimulatorCall + +```solidity +error CanOnlySimulatorCall() +``` + +_Error thrown when a function can only be called by the simulator_ + +### ReceiverError + +```solidity +error ReceiverError(bytes error) +``` + +_Error thrown when there is an error in the receiver_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| error | bytes | The error data | + +### TokenHandlingError + +```solidity +error TokenHandlingError(bytes error) +``` + +_Error thrown when there is an error in token handling_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| error | bytes | The error data | + +### UnsupportedToken + +```solidity +error UnsupportedToken(contract IERC20 token) +``` + +_Error thrown when an unsupported token is encountered_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| token | contract IERC20 | The unsupported token | + +### constructor + +```solidity +constructor(address ccipLocalSimulator, struct MockEvm2EvmOffRamp.DynamicConfig dynamicConfig, struct RateLimiter.Config config, uint64 sourceChainSelector, address[] sourceTokens, address[] pools) public +``` + +Constructor to initialize the contract. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| ccipLocalSimulator | address | - Address of the CCIP local simulator. | +| dynamicConfig | struct MockEvm2EvmOffRamp.DynamicConfig | - Initial dynamic configuration parameters. | +| config | struct RateLimiter.Config | - Rate limiter configuration. | +| sourceChainSelector | uint64 | - Source chain selector. | +| sourceTokens | address[] | - List of supported tokens on the source chain. | +| pools | address[] | - List of pools corresponding to the supported tokens on the source chain. | + +### executeSingleMessage + +```solidity +function executeSingleMessage(struct Internal.EVM2EVMMessage message, bytes[] offchainTokenData) external +``` + +Executes a single CCIP message. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| message | struct Internal.EVM2EVMMessage | - The CCIP message to be executed. | +| offchainTokenData | bytes[] | - Additional off-chain token data. | + +### _releaseOrMintTokens + +```solidity +function _releaseOrMintTokens(struct Client.EVMTokenAmount[] sourceTokenAmounts, bytes originalSender, address receiver, bytes[] sourceTokenData, bytes[] offchainTokenData) internal returns (struct Client.EVMTokenAmount[]) +``` + +Uses pools to release or mint a number of different tokens to a receiver address. + +_This function wraps the token pool call in a try-catch block to gracefully handle +any non-rate limiting errors that may occur. If we encounter a rate limiting related error +we bubble it up. If we encounter a non-rate limiting error we wrap it in a TokenHandlingError._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| sourceTokenAmounts | struct Client.EVMTokenAmount[] | - List of tokens and amount values to be released/minted. | +| originalSender | bytes | - The message sender. | +| receiver | address | - The address that will receive the tokens. | +| sourceTokenData | bytes[] | - Array of token data returned by token pools on the source chain. | +| offchainTokenData | bytes[] | - Array of token data fetched offchain by the DON. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | struct Client.EVMTokenAmount[] | destTokenAmounts - The amounts of tokens released or minted. | + +### getPoolBySourceToken + +```solidity +function getPoolBySourceToken(contract IERC20 sourceToken) public view returns (contract IPool) +``` + +Get a token pool by its source token. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| sourceToken | contract IERC20 | - The source token. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | contract IPool | pool - The corresponding token pool. | + diff --git a/api_reference/ccip/Register.mdx b/api_reference/ccip/Register.mdx new file mode 100644 index 0000000..242b958 --- /dev/null +++ b/api_reference/ccip/Register.mdx @@ -0,0 +1,72 @@ +# Solidity API + +## Register + +This contract allows storing and retrieving network details for various chains. + +_Stores network details in a mapping based on chain IDs._ + +### NetworkDetails + +```solidity +struct NetworkDetails { + uint64 chainSelector; + address routerAddress; + address linkAddress; + address wrappedNativeAddress; + address ccipBnMAddress; + address ccipLnMAddress; +} +``` + +### s_networkDetails + +```solidity +mapping(uint256 => struct Register.NetworkDetails) s_networkDetails +``` + +Mapping to store network details based on chain ID. + +### constructor + +```solidity +constructor() public +``` + +Constructor to initialize the network details for various chains. + +### getNetworkDetails + +```solidity +function getNetworkDetails(uint256 chainId) external view returns (struct Register.NetworkDetails networkDetails) +``` + +Retrieves network details for a given chain ID. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| chainId | uint256 | - The ID of the chain to get the details for. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| networkDetails | struct Register.NetworkDetails | - The network details for the specified chain ID. | + +### setNetworkDetails + +```solidity +function setNetworkDetails(uint256 chainId, struct Register.NetworkDetails networkDetails) external +``` + +Sets the network details for a given chain ID. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| chainId | uint256 | - The ID of the chain to set the details for. | +| networkDetails | struct Register.NetworkDetails | - The network details to set for the specified chain ID. | + diff --git a/api_reference/ccip/index.mdx b/api_reference/ccip/index.mdx new file mode 100644 index 0000000..b9e8417 --- /dev/null +++ b/api_reference/ccip/index.mdx @@ -0,0 +1,7 @@ +# Ccip API Reference + +- [BurnMintERC677Helper](BurnMintERC677Helper.mdx) +- [CCIPLocalSimulator](CCIPLocalSimulator.mdx) +- [CCIPLocalSimulatorFork](CCIPLocalSimulatorFork.mdx) +- [MockEvm2EvmOffRamp](MockEvm2EvmOffRamp.mdx) +- [Register](Register.mdx) diff --git a/api_reference/data-feeds/MockOffchainAggregator.mdx b/api_reference/data-feeds/MockOffchainAggregator.mdx new file mode 100644 index 0000000..b35583a --- /dev/null +++ b/api_reference/data-feeds/MockOffchainAggregator.mdx @@ -0,0 +1,175 @@ +# Solidity API + +## MockOffchainAggregator + +This contract is a mock implementation of an offchain aggregator for testing purposes. + +_This contract simulates the behavior of an offchain aggregator and allows for updating answers and round data._ + +### decimals + +```solidity +uint8 decimals +``` + +The number of decimals used by the aggregator. + +### latestAnswer + +```solidity +int256 latestAnswer +``` + +The latest answer reported by the aggregator. + +### latestTimestamp + +```solidity +uint256 latestTimestamp +``` + +The timestamp of the latest answer. + +### latestRound + +```solidity +uint256 latestRound +``` + +The latest round ID. + +### minAnswer + +```solidity +int192 minAnswer +``` + +The minimum answer the aggregator is allowed to report. + +### maxAnswer + +```solidity +int192 maxAnswer +``` + +The maximum answer the aggregator is allowed to report. + +### getAnswer + +```solidity +mapping(uint256 => int256) getAnswer +``` + +Mapping to get the answer for a specific round ID. + +### getTimestamp + +```solidity +mapping(uint256 => uint256) getTimestamp +``` + +Mapping to get the timestamp for a specific round ID. + +### constructor + +```solidity +constructor(uint8 _decimals, int256 _initialAnswer) public +``` + +Constructor to initialize the MockOffchainAggregator contract with initial parameters. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _decimals | uint8 | - The number of decimals for the aggregator. | +| _initialAnswer | int256 | - The initial answer to be set in the mock aggregator. | + +### updateAnswer + +```solidity +function updateAnswer(int256 _answer) public +``` + +Updates the answer in the mock aggregator. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _answer | int256 | - The new answer to be set. | + +### updateRoundData + +```solidity +function updateRoundData(uint80 _roundId, int256 _answer, uint256 _timestamp, uint256 _startedAt) public +``` + +Updates the round data in the mock aggregator. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _roundId | uint80 | - The round ID to be updated. | +| _answer | int256 | - The new answer to be set. | +| _timestamp | uint256 | - The timestamp to be set. | +| _startedAt | uint256 | - The timestamp when the round started. | + +### getRoundData + +```solidity +function getRoundData(uint80 _roundId) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +``` + +Gets the round data for a specific round ID. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _roundId | uint80 | - The round ID to get the data for. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint80 | - The round ID. | +| answer | int256 | - The answer for the round. | +| startedAt | uint256 | - The timestamp when the round started. | +| updatedAt | uint256 | - The timestamp when the round was updated. | +| answeredInRound | uint80 | - The round ID in which the answer was computed. | + +### latestRoundData + +```solidity +function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +``` + +Gets the latest round data. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint80 | - The latest round ID. | +| answer | int256 | - The latest answer. | +| startedAt | uint256 | - The timestamp when the latest round started. | +| updatedAt | uint256 | - The timestamp when the latest round was updated. | +| answeredInRound | uint80 | - The round ID in which the latest answer was computed. | + +### updateMinAndMaxAnswers + +```solidity +function updateMinAndMaxAnswers(int192 _minAnswer, int192 _maxAnswer) external +``` + +Updates the minimum and maximum answers the aggregator can report. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _minAnswer | int192 | - The new minimum answer. | +| _maxAnswer | int192 | - The new maximum answer. | + diff --git a/api_reference/data-feeds/MockV3Aggregator.mdx b/api_reference/data-feeds/MockV3Aggregator.mdx new file mode 100644 index 0000000..e89dc53 --- /dev/null +++ b/api_reference/data-feeds/MockV3Aggregator.mdx @@ -0,0 +1,262 @@ +# Solidity API + +## MockV3Aggregator + +This contract is a mock implementation of the AggregatorV2V3Interface for testing purposes. + +_This contract interacts with a MockOffchainAggregator to simulate price feeds._ + +### version + +```solidity +uint256 version +``` + +The version of the aggregator. + +### aggregator + +```solidity +address aggregator +``` + +The address of the current aggregator. + +### proposedAggregator + +```solidity +address proposedAggregator +``` + +The address of the proposed aggregator. + +### constructor + +```solidity +constructor(uint8 _decimals, int256 _initialAnswer) public +``` + +Constructor to initialize the MockV3Aggregator contract with initial parameters. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _decimals | uint8 | - The number of decimals for the aggregator. | +| _initialAnswer | int256 | - The initial answer to be set in the mock aggregator. | + +### decimals + +```solidity +function decimals() external view returns (uint8) +``` + +Gets the number of decimals used by the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint8 | uint8 - The number of decimals. | + +### getAnswer + +```solidity +function getAnswer(uint256 roundId) external view returns (int256) +``` + +Gets the answer for a specific round ID. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint256 | - The round ID to get the answer for. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | int256 | int256 - The answer for the given round ID. | + +### getRoundData + +```solidity +function getRoundData(uint80 _roundId) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +``` + +Gets the round data for a specific round ID. + +_This function should raise "No data present" if no data is available for the given round ID._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _roundId | uint80 | - The round ID to get the data for. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint80 | - The round ID. | +| answer | int256 | - The answer for the round. | +| startedAt | uint256 | - The timestamp when the round started. | +| updatedAt | uint256 | - The timestamp when the round was updated. | +| answeredInRound | uint80 | - The round ID in which the answer was computed. | + +### latestRoundData + +```solidity +function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +``` + +Gets the latest round data. + +_This function should raise "No data present" if no data is available._ + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint80 | - The latest round ID. | +| answer | int256 | - The latest answer. | +| startedAt | uint256 | - The timestamp when the latest round started. | +| updatedAt | uint256 | - The timestamp when the latest round was updated. | +| answeredInRound | uint80 | - The round ID in which the latest answer was computed. | + +### getTimestamp + +```solidity +function getTimestamp(uint256 roundId) external view returns (uint256) +``` + +Gets the timestamp for a specific round ID. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint256 | - The round ID to get the timestamp for. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint256 - The timestamp for the given round ID. | + +### latestAnswer + +```solidity +function latestAnswer() external view returns (int256) +``` + +Gets the latest answer from the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | int256 | int256 - The latest answer. | + +### latestTimestamp + +```solidity +function latestTimestamp() external view returns (uint256) +``` + +Gets the timestamp of the latest answer from the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint256 - The timestamp of the latest answer. | + +### latestRound + +```solidity +function latestRound() external view returns (uint256) +``` + +Gets the latest round ID from the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint256 - The latest round ID. | + +### updateAnswer + +```solidity +function updateAnswer(int256 _answer) public +``` + +Updates the answer in the mock aggregator. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _answer | int256 | - The new answer to be set. | + +### updateRoundData + +```solidity +function updateRoundData(uint80 _roundId, int256 _answer, uint256 _timestamp, uint256 _startedAt) public +``` + +Updates the round data in the mock aggregator. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _roundId | uint80 | - The round ID to be updated. | +| _answer | int256 | - The new answer to be set. | +| _timestamp | uint256 | - The timestamp to be set. | +| _startedAt | uint256 | - The timestamp when the round started. | + +### proposeAggregator + +```solidity +function proposeAggregator(contract AggregatorV2V3Interface _aggregator) external +``` + +Proposes a new aggregator. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _aggregator | contract AggregatorV2V3Interface | - The address of the proposed aggregator. | + +### confirmAggregator + +```solidity +function confirmAggregator(address _aggregator) external +``` + +Confirms the proposed aggregator. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _aggregator | address | - The address of the proposed aggregator. | + +### description + +```solidity +function description() external pure returns (string) +``` + +Gets the description of the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | string | string memory - The description of the aggregator. | + diff --git a/api_reference/data-feeds/index.mdx b/api_reference/data-feeds/index.mdx new file mode 100644 index 0000000..b7d0bdb --- /dev/null +++ b/api_reference/data-feeds/index.mdx @@ -0,0 +1,5 @@ +# Data-feeds API Reference + +- [MockOffchainAggregator](MockOffchainAggregator.mdx) +- [MockV3Aggregator](MockV3Aggregator.mdx) +- [interfaces](interfaces/index.mdx) diff --git a/api_reference/data-feeds/interfaces/AggregatorInterface.mdx b/api_reference/data-feeds/interfaces/AggregatorInterface.mdx new file mode 100644 index 0000000..db4d7b3 --- /dev/null +++ b/api_reference/data-feeds/interfaces/AggregatorInterface.mdx @@ -0,0 +1,122 @@ +# Solidity API + +## AggregatorInterface + +Interface for accessing data from an aggregator contract. + +_Provides methods to get the latest data and historical data for specific rounds._ + +### latestAnswer + +```solidity +function latestAnswer() external view returns (int256) +``` + +Gets the latest answer from the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | int256 | int256 - The latest answer. | + +### latestTimestamp + +```solidity +function latestTimestamp() external view returns (uint256) +``` + +Gets the timestamp of the latest answer from the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint256 - The timestamp of the latest answer. | + +### latestRound + +```solidity +function latestRound() external view returns (uint256) +``` + +Gets the latest round ID from the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint256 - The latest round ID. | + +### getAnswer + +```solidity +function getAnswer(uint256 roundId) external view returns (int256) +``` + +Gets the answer for a specific round ID. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint256 | - The round ID to get the answer for. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | int256 | int256 - The answer for the given round ID. | + +### getTimestamp + +```solidity +function getTimestamp(uint256 roundId) external view returns (uint256) +``` + +Gets the timestamp for a specific round ID. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint256 | - The round ID to get the timestamp for. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint256 - The timestamp for the given round ID. | + +### AnswerUpdated + +```solidity +event AnswerUpdated(int256 current, uint256 roundId, uint256 updatedAt) +``` + +Emitted when the answer is updated. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| current | int256 | - The updated answer. | +| roundId | uint256 | - The round ID for which the answer was updated. | +| updatedAt | uint256 | - The timestamp when the answer was updated. | + +### NewRound + +```solidity +event NewRound(uint256 roundId, address startedBy, uint256 startedAt) +``` + +Emitted when a new round is started. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint256 | - The round ID of the new round. | +| startedBy | address | - The address of the account that started the round. | +| startedAt | uint256 | - The timestamp when the round was started. | + diff --git a/api_reference/data-feeds/interfaces/AggregatorV2V3Interface.mdx b/api_reference/data-feeds/interfaces/AggregatorV2V3Interface.mdx new file mode 100644 index 0000000..497e3dc --- /dev/null +++ b/api_reference/data-feeds/interfaces/AggregatorV2V3Interface.mdx @@ -0,0 +1,6 @@ +# Solidity API + +## AggregatorV2V3Interface + +Interface that inherits from both AggregatorInterface and AggregatorV3Interface. + diff --git a/api_reference/data-feeds/interfaces/AggregatorV3Interface.mdx b/api_reference/data-feeds/interfaces/AggregatorV3Interface.mdx new file mode 100644 index 0000000..8cc4bee --- /dev/null +++ b/api_reference/data-feeds/interfaces/AggregatorV3Interface.mdx @@ -0,0 +1,96 @@ +# Solidity API + +## AggregatorV3Interface + +Interface for accessing detailed data from an aggregator contract, including round data and metadata. + +_Provides methods to get the latest data, historical data for specific rounds, and metadata such as decimals and description._ + +### decimals + +```solidity +function decimals() external view returns (uint8) +``` + +Gets the number of decimals used by the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint8 | uint8 - The number of decimals. | + +### description + +```solidity +function description() external view returns (string) +``` + +Gets the description of the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | string | string memory - The description of the aggregator. | + +### version + +```solidity +function version() external view returns (uint256) +``` + +Gets the version of the aggregator. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint256 - The version of the aggregator. | + +### getRoundData + +```solidity +function getRoundData(uint80 _roundId) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +``` + +Gets the round data for a specific round ID. + +_This function should raise "No data present" if no data is available for the given round ID._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _roundId | uint80 | - The round ID to get the data for. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint80 | - The round ID. | +| answer | int256 | - The answer for the round. | +| startedAt | uint256 | - The timestamp when the round started. | +| updatedAt | uint256 | - The timestamp when the round was updated. | +| answeredInRound | uint80 | - The round ID in which the answer was computed. | + +### latestRoundData + +```solidity +function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +``` + +Gets the latest round data. + +_This function should raise "No data present" if no data is available._ + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| roundId | uint80 | - The latest round ID. | +| answer | int256 | - The latest answer. | +| startedAt | uint256 | - The timestamp when the latest round started. | +| updatedAt | uint256 | - The timestamp when the latest round was updated. | +| answeredInRound | uint80 | - The round ID in which the latest answer was computed. | + diff --git a/api_reference/data-feeds/interfaces/index.mdx b/api_reference/data-feeds/interfaces/index.mdx new file mode 100644 index 0000000..62baf78 --- /dev/null +++ b/api_reference/data-feeds/interfaces/index.mdx @@ -0,0 +1,5 @@ +# Interfaces API Reference + +- [AggregatorInterface](AggregatorInterface.mdx) +- [AggregatorV2V3Interface](AggregatorV2V3Interface.mdx) +- [AggregatorV3Interface](AggregatorV3Interface.mdx) diff --git a/api_reference/index.mdx b/api_reference/index.mdx new file mode 100644 index 0000000..3c02f81 --- /dev/null +++ b/api_reference/index.mdx @@ -0,0 +1,5 @@ +# API Reference + +- [ccip](ccip/index.mdx) +- [data-feeds](data-feeds/index.mdx) +- [shared](shared/index.mdx) diff --git a/api_reference/shared/LinkToken.mdx b/api_reference/shared/LinkToken.mdx new file mode 100644 index 0000000..dde4845 --- /dev/null +++ b/api_reference/shared/LinkToken.mdx @@ -0,0 +1,29 @@ +# Solidity API + +## LinkToken + +This contract implements the ChainLink Token (LINK) using the ERC677 standard. + +_Inherits from the ERC677 token contract and initializes with a fixed total supply and standard token details._ + +### constructor + +```solidity +constructor() public +``` + +Constructor to initialize the LinkToken contract with a fixed total supply, name, and symbol. + +_Calls the ERC677 constructor with the name and symbol, and then mints the total supply to the contract deployer._ + +### _onCreate + +```solidity +function _onCreate() internal virtual +``` + +Hook that is called when this contract is created. + +_Useful to override constructor behaviour in child contracts (e.g., LINK bridge tokens). + The default implementation mints 10**27 tokens to the contract deployer._ + diff --git a/api_reference/shared/WETH9.mdx b/api_reference/shared/WETH9.mdx new file mode 100644 index 0000000..b4ef5be --- /dev/null +++ b/api_reference/shared/WETH9.mdx @@ -0,0 +1,106 @@ +# Solidity API + +## WETH9 + +### name + +```solidity +string name +``` + +### symbol + +```solidity +string symbol +``` + +### decimals + +```solidity +uint8 decimals +``` + +### Approval + +```solidity +event Approval(address src, address guy, uint256 wad) +``` + +### Transfer + +```solidity +event Transfer(address src, address dst, uint256 wad) +``` + +### Deposit + +```solidity +event Deposit(address dst, uint256 wad) +``` + +### Withdrawal + +```solidity +event Withdrawal(address src, uint256 wad) +``` + +### balanceOf + +```solidity +mapping(address => uint256) balanceOf +``` + +### allowance + +```solidity +mapping(address => mapping(address => uint256)) allowance +``` + +### receive + +```solidity +receive() external payable +``` + +### _deposit + +```solidity +function _deposit() internal +``` + +### deposit + +```solidity +function deposit() external payable +``` + +### withdraw + +```solidity +function withdraw(uint256 wad) external +``` + +### totalSupply + +```solidity +function totalSupply() public view returns (uint256) +``` + +### approve + +```solidity +function approve(address guy, uint256 wad) public returns (bool) +``` + +### transfer + +```solidity +function transfer(address dst, uint256 wad) public returns (bool) +``` + +### transferFrom + +```solidity +function transferFrom(address src, address dst, uint256 wad) public returns (bool) +``` + diff --git a/api_reference/shared/index.mdx b/api_reference/shared/index.mdx new file mode 100644 index 0000000..d8a2e0c --- /dev/null +++ b/api_reference/shared/index.mdx @@ -0,0 +1,4 @@ +# Shared API Reference + +- [LinkToken](LinkToken.mdx) +- [WETH9](WETH9.mdx) diff --git a/generate-index-files.ts b/generate-index-files.ts new file mode 100644 index 0000000..042894b --- /dev/null +++ b/generate-index-files.ts @@ -0,0 +1,54 @@ +import fs from "fs-extra"; +import path from "path"; + +const MDX_EXTENSION = ".mdx"; +const rootDir = path.join(__dirname, "api_reference"); + +const generateIndexFile = async (dir: string, header: string) => { + const files = await fs.readdir(dir); + const mdxFiles = files.filter( + (file) => file.endsWith(MDX_EXTENSION) && file !== `index${MDX_EXTENSION}` + ); + const subDirs = files.filter((file) => + fs.lstatSync(path.join(dir, file)).isDirectory() + ); + + let content = `# ${header}\n\n`; + + const allEntries = [...mdxFiles, ...subDirs]; + + if (allEntries.length > 0) { + allEntries.forEach((entry) => { + const fileNameWithoutExtension = path.basename(entry, MDX_EXTENSION); + const linkName = entry.endsWith(MDX_EXTENSION) + ? fileNameWithoutExtension + : entry; + const linkPath = entry.endsWith(MDX_EXTENSION) + ? entry + : `${entry}/index${MDX_EXTENSION}`; + content += `- [${linkName}](${linkPath})\n`; + }); + } + + await fs.writeFile(path.join(dir, `index${MDX_EXTENSION}`), content); +}; + +const traverseDirectory = async (dir: string, header: string) => { + await generateIndexFile(dir, header); + + const files = await fs.readdir(dir); + const subDirs = files.filter((file) => + fs.lstatSync(path.join(dir, file)).isDirectory() + ); + + for (const subDir of subDirs) { + await traverseDirectory( + path.join(dir, subDir), + `${subDir.charAt(0).toUpperCase() + subDir.slice(1)} API Reference` + ); + } +}; + +traverseDirectory(rootDir, "API Reference") + .then(() => console.log("Index files generated successfully.")) + .catch((err) => console.error(err)); diff --git a/hardhat.config.ts b/hardhat.config.ts index 6adfd32..fb14665 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,15 +1,23 @@ -import * as dotenv from "dotenv" +import * as dotenv from "dotenv"; +import "solidity-docgen"; import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; import "@nomicfoundation/hardhat-foundry"; -dotenv.config() +dotenv.config(); const config: HardhatUserConfig = { solidity: "0.8.19", paths: { - sources: './src' + sources: "./src", + }, + docgen: { + pages: "files", + pageExtension: ".mdx", + templates: "custom_templates", + exclude: ["test"], + outputDir: "api_reference", }, }; diff --git a/package-lock.json b/package-lock.json index 691ce5b..81ac1f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@chainlink/local", - "version": "0.1.0", + "version": "0.2.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@chainlink/local", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@chainlink/contracts": "^1.1.1", @@ -15,8 +15,11 @@ "devDependencies": { "@nomicfoundation/hardhat-foundry": "^1.1.1", "@nomicfoundation/hardhat-toolbox": "^4.0.0", + "@types/fs-extra": "^11.0.4", "dotenv": "^16.4.5", - "hardhat": "^2.20.1" + "fs-extra": "^11.2.0", + "hardhat": "^2.20.1", + "solidity-docgen": "^0.6.0-beta.36" } }, "node_modules/@adraffy/ens-normalize": { @@ -2902,6 +2905,23 @@ "typechain": "^8.3.2" } }, + "node_modules/@typechain/hardhat/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@types/bn.js": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", @@ -2957,6 +2977,17 @@ "@types/node": "*" } }, + "node_modules/@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/jsonfile": "*", + "@types/node": "*" + } + }, "node_modules/@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", @@ -2990,6 +3021,16 @@ "node": ">=8" } }, + "node_modules/@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", @@ -3323,7 +3364,7 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "optional": true, + "devOptional": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -3428,6 +3469,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", "engines": { "node": ">= 4.0.0" } @@ -5274,17 +5316,18 @@ "dev": true }, "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=14.14" } }, "node_modules/fs-readdir-recursive": { @@ -5538,7 +5581,7 @@ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", @@ -5560,7 +5603,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7207,8 +7249,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/nice-try": { "version": "1.0.5", @@ -7607,6 +7648,21 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/patch-package/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/patch-package/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -9095,7 +9151,7 @@ "version": "0.4.56", "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.56.tgz", "integrity": "sha512-HgmsA/Gfklm/M8GFbCX/J1qkVH0spXHgALCNZ8fA8x5X+MFdn/8CP2gr5OVyXjXw6RZTPC/Sxl2RUDQOXyNMeA==", - "optional": true, + "devOptional": true, "dependencies": { "array.prototype.findlast": "^1.2.2" } @@ -9205,6 +9261,20 @@ "node": ">= 4.0.0" } }, + "node_modules/solidity-docgen": { + "version": "0.6.0-beta.36", + "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.6.0-beta.36.tgz", + "integrity": "sha512-f/I5G2iJgU1h0XrrjRD0hHMr7C10u276vYvm//rw1TzFcYQ4xTOyAoi9oNAHRU0JU4mY9eTuxdVc2zahdMuhaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "handlebars": "^4.7.7", + "solidity-ast": "^0.4.38" + }, + "peerDependencies": { + "hardhat": "^2.8.0" + } + }, "node_modules/source-map": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", @@ -10197,7 +10267,6 @@ "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", "dev": true, "optional": true, - "peer": true, "bin": { "uglifyjs": "bin/uglifyjs" }, @@ -10478,8 +10547,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/wordwrapjs": { "version": "4.0.1", @@ -12784,6 +12852,21 @@ "peer": true, "requires": { "fs-extra": "^9.1.0" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "peer": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + } } }, "@types/bn.js": { @@ -12841,6 +12924,16 @@ "@types/node": "*" } }, + "@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "dev": true, + "requires": { + "@types/jsonfile": "*", + "@types/node": "*" + } + }, "@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", @@ -12867,6 +12960,15 @@ } } }, + "@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", @@ -13144,7 +13246,7 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "optional": true, + "devOptional": true, "requires": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -14678,11 +14780,11 @@ "dev": true }, "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, "requires": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" @@ -14869,7 +14971,6 @@ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, - "peer": true, "requires": { "minimist": "^1.2.5", "neo-async": "^2.6.2", @@ -14882,8 +14983,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "peer": true + "dev": true } } }, @@ -16091,8 +16191,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "peer": true + "dev": true }, "nice-try": { "version": "1.0.5", @@ -16389,6 +16488,17 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -17483,7 +17593,7 @@ "version": "0.4.56", "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.56.tgz", "integrity": "sha512-HgmsA/Gfklm/M8GFbCX/J1qkVH0spXHgALCNZ8fA8x5X+MFdn/8CP2gr5OVyXjXw6RZTPC/Sxl2RUDQOXyNMeA==", - "optional": true, + "devOptional": true, "requires": { "array.prototype.findlast": "^1.2.2" } @@ -17574,6 +17684,16 @@ } } }, + "solidity-docgen": { + "version": "0.6.0-beta.36", + "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.6.0-beta.36.tgz", + "integrity": "sha512-f/I5G2iJgU1h0XrrjRD0hHMr7C10u276vYvm//rw1TzFcYQ4xTOyAoi9oNAHRU0JU4mY9eTuxdVc2zahdMuhaQ==", + "dev": true, + "requires": { + "handlebars": "^4.7.7", + "solidity-ast": "^0.4.38" + } + }, "source-map": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", @@ -18335,8 +18455,7 @@ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", "dev": true, - "optional": true, - "peer": true + "optional": true }, "unbox-primitive": { "version": "1.0.2", @@ -18564,8 +18683,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "peer": true + "dev": true }, "wordwrapjs": { "version": "4.0.1", diff --git a/package.json b/package.json index e5246cf..a7911a8 100644 --- a/package.json +++ b/package.json @@ -21,16 +21,20 @@ "forge-compile": "forge build", "hardhat-test": "npx hardhat test", "forge-test": "forge test", - "test": "npm run hardhat-test && npm run forge-test" + "test": "npm run hardhat-test && npm run forge-test", + "generate-apiref": "npm run hardhat-compile && npm run forge-compile && npx hardhat docgen && npx ts-node generate-index-files.ts" }, "devDependencies": { "@nomicfoundation/hardhat-foundry": "^1.1.1", "@nomicfoundation/hardhat-toolbox": "^4.0.0", + "@types/fs-extra": "^11.0.4", "dotenv": "^16.4.5", - "hardhat": "^2.20.1" + "fs-extra": "^11.2.0", + "hardhat": "^2.20.1", + "solidity-docgen": "^0.6.0-beta.36" }, "dependencies": { "@chainlink/contracts": "^1.1.1", "@chainlink/contracts-ccip": "^1.4.0" } -} \ No newline at end of file +} diff --git a/src/ccip/BurnMintERC677Helper.sol b/src/ccip/BurnMintERC677Helper.sol index c73bc02..71c2aaa 100644 --- a/src/ccip/BurnMintERC677Helper.sol +++ b/src/ccip/BurnMintERC677Helper.sol @@ -3,13 +3,26 @@ pragma solidity ^0.8.19; import {BurnMintERC677} from "@chainlink/contracts-ccip/src/v0.8/shared/token/ERC677/BurnMintERC677.sol"; +/// @title BurnMintERC677Helper +/// @notice This contract extends the functionality of the BurnMintERC677 token contract to include a `drip` function that mints one full token to a specified address. +/// @dev Inherits from the BurnMintERC677 contract and sets the token name, symbol, decimals, and initial supply in the constructor. contract BurnMintERC677Helper is BurnMintERC677 { + /** + * @notice Constructor to initialize the BurnMintERC677Helper contract with a name and symbol. + * @dev Calls the parent constructor of BurnMintERC677 with fixed decimals (18) and initial supply (0). + * @param name - The name of the token. + * @param symbol - The symbol of the token. + */ constructor( string memory name, string memory symbol ) BurnMintERC677(name, symbol, 18, 0) {} - // Gives one full token to any given address. + /** + * @notice Mints one full token (1e18) to the specified address. + * @dev Calls the internal `_mint` function from the BurnMintERC677 contract. + * @param to - The address to receive the minted token. + */ function drip(address to) external { _mint(to, 1e18); } diff --git a/src/ccip/CCIPLocalSimulator.sol b/src/ccip/CCIPLocalSimulator.sol index 59aec6c..3e3d8a3 100644 --- a/src/ccip/CCIPLocalSimulator.sol +++ b/src/ccip/CCIPLocalSimulator.sol @@ -9,19 +9,36 @@ import {IRouterClient} from "@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/ import {IERC20} from "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +/// @title CCIPLocalSimulator +/// @notice This contract simulates local CCIP (Cross-Chain Interoperability Protocol) operations for testing and development purposes. +/// @dev This contract includes methods to manage supported tokens and configurations for local simulations. contract CCIPLocalSimulator { using SafeERC20 for IERC20; + /// @notice The unique CCIP Chain Selector constant uint64 constant CHAIN_SELECTOR = 16015286601757825753; + /// @notice The wrapped native token instance WETH9 internal immutable i_wrappedNative; + + /// @notice The LINK token instance LinkToken internal immutable i_linkToken; + + /// @notice The BurnMintERC677Helper instance for CCIP-BnM token BurnMintERC677Helper internal immutable i_ccipBnM; + + /// @notice The BurnMintERC677Helper instance for CCIP-LnM token BurnMintERC677Helper internal immutable i_ccipLnM; + + /// @notice The mock CCIP router instance MockCCIPRouter internal immutable i_mockRouter; + /// @notice The list of supported token addresses address[] internal s_supportedTokens; + /** + * @notice Constructor to initialize the contract and pre-deployed token instances + */ constructor() { i_wrappedNative = new WETH9(); i_linkToken = new LinkToken(); diff --git a/src/ccip/CCIPLocalSimulatorFork.sol b/src/ccip/CCIPLocalSimulatorFork.sol index 449bfca..5e394f0 100644 --- a/src/ccip/CCIPLocalSimulatorFork.sol +++ b/src/ccip/CCIPLocalSimulatorFork.sol @@ -4,31 +4,65 @@ pragma solidity ^0.8.19; import {Test, Vm} from "forge-std/Test.sol"; import {Register} from "./Register.sol"; import {Internal} from "@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Internal.sol"; -import {IERC20} from - "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {IERC20} from "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +/// @title IRouterFork Interface interface IRouterFork { + /** + * @notice Structure representing an offRamp configuration + * + * @param sourceChainSelector - The chain selector for the source chain + * @param offRamp - The address of the offRamp contract + */ struct OffRamp { uint64 sourceChainSelector; address offRamp; } + /** + * @notice Gets the list of offRamps + * + * @return offRamps - Array of OffRamp structs + */ function getOffRamps() external view returns (OffRamp[] memory); } +/// @title IEVM2EVMOffRampFork Interface interface IEVM2EVMOffRampFork { - function executeSingleMessage(Internal.EVM2EVMMessage memory message, bytes[] memory offchainTokenData) external; + /** + * @notice Executes a single CCIP message on the offRamp + * + * @param message - The CCIP message to be executed + * @param offchainTokenData - Additional offchain token data + */ + function executeSingleMessage( + Internal.EVM2EVMMessage memory message, + bytes[] memory offchainTokenData + ) external; } -// @notice Works with Foundry only +/// @title CCIPLocalSimulatorFork +/// @notice Works with Foundry only contract CCIPLocalSimulatorFork is Test { + /** + * @notice Event emitted when a CCIP send request is made + * + * @param message - The EVM2EVM message that was sent + */ event CCIPSendRequested(Internal.EVM2EVMMessage message); + /// @notice The immutable register instance Register immutable i_register; + + /// @notice The address of the LINK faucet address constant LINK_FAUCET = 0x4281eCF07378Ee595C564a59048801330f3084eE; + /// @notice Mapping to track processed messages mapping(bytes32 messageId => bool isProcessed) internal s_processedMessages; + /** + * @notice Constructor to initialize the contract + */ constructor() { vm.recordLogs(); i_register = new Register(); @@ -46,7 +80,10 @@ contract CCIPLocalSimulatorFork is Test { uint256 length = entries.length; for (uint256 i; i < length; ++i) { if (entries[i].topics[0] == CCIPSendRequested.selector) { - message = abi.decode(entries[i].data, (Internal.EVM2EVMMessage)); + message = abi.decode( + entries[i].data, + (Internal.EVM2EVMMessage) + ); if (!s_processedMessages[message.messageId]) { s_processedMessages[message.messageId] = true; break; @@ -57,16 +94,22 @@ contract CCIPLocalSimulatorFork is Test { vm.selectFork(forkId); assertEq(vm.activeFork(), forkId); - IRouterFork.OffRamp[] memory offRamps = - IRouterFork(i_register.getNetworkDetails(block.chainid).routerAddress).getOffRamps(); + IRouterFork.OffRamp[] memory offRamps = IRouterFork( + i_register.getNetworkDetails(block.chainid).routerAddress + ).getOffRamps(); length = offRamps.length; for (uint256 i; i < length; ++i) { - if (offRamps[i].sourceChainSelector == message.sourceChainSelector) { + if ( + offRamps[i].sourceChainSelector == message.sourceChainSelector + ) { vm.startPrank(offRamps[i].offRamp); uint256 numberOfTokens = message.tokenAmounts.length; bytes[] memory offchainTokenData = new bytes[](numberOfTokens); - IEVM2EVMOffRampFork(offRamps[i].offRamp).executeSingleMessage(message, offchainTokenData); + IEVM2EVMOffRampFork(offRamps[i].offRamp).executeSingleMessage( + message, + offchainTokenData + ); vm.stopPrank(); break; } @@ -86,7 +129,9 @@ contract CCIPLocalSimulatorFork is Test { * ccipBnMAddress - The address of the CCIP BnM token. * ccipLnMAddress - The address of the CCIP LnM token. */ - function getNetworkDetails(uint256 chainId) external view returns (Register.NetworkDetails memory) { + function getNetworkDetails( + uint256 chainId + ) external view returns (Register.NetworkDetails memory) { return i_register.getNetworkDetails(chainId); } @@ -102,7 +147,10 @@ contract CCIPLocalSimulatorFork is Test { * ccipBnMAddress - The address of the CCIP BnM token. * ccipLnMAddress - The address of the CCIP LnM token. */ - function setNetworkDetails(uint256 chainId, Register.NetworkDetails memory networkDetails) external { + function setNetworkDetails( + uint256 chainId, + Register.NetworkDetails memory networkDetails + ) external { i_register.setNetworkDetails(chainId, networkDetails); } @@ -114,8 +162,13 @@ contract CCIPLocalSimulatorFork is Test { * * @return success - Returns `true` if the transfer of tokens was successful, otherwise `false`. */ - function requestLinkFromFaucet(address to, uint256 amount) external returns (bool success) { - address linkAddress = i_register.getNetworkDetails(block.chainid).linkAddress; + function requestLinkFromFaucet( + address to, + uint256 amount + ) external returns (bool success) { + address linkAddress = i_register + .getNetworkDetails(block.chainid) + .linkAddress; vm.startPrank(LINK_FAUCET); success = IERC20(linkAddress).transfer(to, amount); diff --git a/src/ccip/MockEvm2EvmOffRamp.sol b/src/ccip/MockEvm2EvmOffRamp.sol index 823bc88..33ea348 100644 --- a/src/ccip/MockEvm2EvmOffRamp.sol +++ b/src/ccip/MockEvm2EvmOffRamp.sol @@ -16,6 +16,8 @@ import {IERC20} from "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-sol import {Address} from "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/Address.sol"; import {ERC165Checker} from "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; +/// @title MockEvm2EvmOffRamp +/// @notice This contract handles off-ramp processes for CCIP messages contract MockEvm2EvmOffRamp is AggregateRateLimiter { using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; using USDPriceWith18Decimals for uint224; @@ -31,19 +33,43 @@ contract MockEvm2EvmOffRamp is AggregateRateLimiter { uint32 maxPoolReleaseOrMintGas; // ─╯ Maximum amount of gas passed on to token pool when calling releaseOrMint } + /// @dev chain selector for the source chain uint64 internal immutable i_sourceChainSelector; + /// @dev Address of the CCIP Local Simulator address internal s_ccipLocalSimulator; + + /// @dev Dynamic configuration of the offramp DynamicConfig internal s_dynamicConfig; - /// @dev source token => token pool + /// @dev Map from source token to token pool EnumerableMapAddresses.AddressToAddressMap private s_poolsBySourceToken; + /// @dev Error thrown when a function can only be called by the simulator error CanOnlySimulatorCall(); + + /// @dev Error thrown when there is an error in the receiver + /// @param error The error data error ReceiverError(bytes error); + + /// @dev Error thrown when there is an error in token handling + /// @param error The error data error TokenHandlingError(bytes error); + + /// @dev Error thrown when an unsupported token is encountered + /// @param token The unsupported token error UnsupportedToken(IERC20 token); + /** + * @notice Constructor to initialize the contract. + * + * @param ccipLocalSimulator - Address of the CCIP local simulator. + * @param dynamicConfig - Initial dynamic configuration parameters. + * @param config - Rate limiter configuration. + * @param sourceChainSelector - Source chain selector. + * @param sourceTokens - List of supported tokens on the source chain. + * @param pools - List of pools corresponding to the supported tokens on the source chain. + */ constructor( address ccipLocalSimulator, DynamicConfig memory dynamicConfig, @@ -66,6 +92,12 @@ contract MockEvm2EvmOffRamp is AggregateRateLimiter { } } + /** + * @notice Executes a single CCIP message. + * + * @param message - The CCIP message to be executed. + * @param offchainTokenData - Additional off-chain token data. + */ function executeSingleMessage( Internal.EVM2EVMMessage memory message, bytes[] memory offchainTokenData @@ -102,15 +134,20 @@ contract MockEvm2EvmOffRamp is AggregateRateLimiter { if (!success) revert ReceiverError(returnData); } - /// @notice Uses pools to release or mint a number of different tokens to a receiver address. - /// @param sourceTokenAmounts List of tokens and amount values to be released/minted. - /// @param originalSender The message sender. - /// @param receiver The address that will receive the tokens. - /// @param sourceTokenData Array of token data returned by token pools on the source chain. - /// @param offchainTokenData Array of token data fetched offchain by the DON. - /// @dev This function wrappes the token pool call in a try catch block to gracefully handle - /// any non-rate limiting errors that may occur. If we encounter a rate limiting related error - /// we bubble it up. If we encounter a non-rate limiting error we wrap it in a TokenHandlingError. + /** + * @notice Uses pools to release or mint a number of different tokens to a receiver address. + * + * @param sourceTokenAmounts - List of tokens and amount values to be released/minted. + * @param originalSender - The message sender. + * @param receiver - The address that will receive the tokens. + * @param sourceTokenData - Array of token data returned by token pools on the source chain. + * @param offchainTokenData - Array of token data fetched offchain by the DON. + * @return destTokenAmounts - The amounts of tokens released or minted. + * + * @dev This function wraps the token pool call in a try-catch block to gracefully handle + * any non-rate limiting errors that may occur. If we encounter a rate limiting related error + * we bubble it up. If we encounter a non-rate limiting error we wrap it in a TokenHandlingError. + */ function _releaseOrMintTokens( Client.EVMTokenAmount[] memory sourceTokenAmounts, bytes memory originalSender, @@ -160,9 +197,12 @@ contract MockEvm2EvmOffRamp is AggregateRateLimiter { return destTokenAmounts; } - /// @notice Get a token pool by its source token - /// @param sourceToken token - /// @return Token Pool + /** + * @notice Get a token pool by its source token. + * + * @param sourceToken - The source token. + * @return pool - The corresponding token pool. + */ function getPoolBySourceToken( IERC20 sourceToken ) public view returns (IPool) { diff --git a/src/ccip/Register.sol b/src/ccip/Register.sol index fc6bd3a..b6f1e4b 100644 --- a/src/ccip/Register.sol +++ b/src/ccip/Register.sol @@ -1,6 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.19; +/// @title Register Contract +/// @notice This contract allows storing and retrieving network details for various chains. +/// @dev Stores network details in a mapping based on chain IDs. contract Register { struct NetworkDetails { uint64 chainSelector; @@ -11,8 +14,10 @@ contract Register { address ccipLnMAddress; } + /// @notice Mapping to store network details based on chain ID. mapping(uint256 chainId => NetworkDetails) internal s_networkDetails; + /// @notice Constructor to initialize the network details for various chains. constructor() { // Ethereum Sepolia s_networkDetails[11155111] = NetworkDetails({ @@ -106,11 +111,28 @@ contract Register { }); } - function getNetworkDetails(uint256 chainId) external view returns (NetworkDetails memory) { - return s_networkDetails[chainId]; + /** + * @notice Retrieves network details for a given chain ID. + * + * @param chainId - The ID of the chain to get the details for. + * @return networkDetails - The network details for the specified chain ID. + */ + function getNetworkDetails( + uint256 chainId + ) external view returns (NetworkDetails memory networkDetails) { + networkDetails = s_networkDetails[chainId]; } - function setNetworkDetails(uint256 chainId, NetworkDetails memory networkDetails) external { + /** + * @notice Sets the network details for a given chain ID. + * + * @param chainId - The ID of the chain to set the details for. + * @param networkDetails - The network details to set for the specified chain ID. + */ + function setNetworkDetails( + uint256 chainId, + NetworkDetails memory networkDetails + ) external { s_networkDetails[chainId] = networkDetails; } } diff --git a/src/data-feeds/MockOffchainAggregator.sol b/src/data-feeds/MockOffchainAggregator.sol index 2dd8706..89f378f 100644 --- a/src/data-feeds/MockOffchainAggregator.sol +++ b/src/data-feeds/MockOffchainAggregator.sol @@ -1,35 +1,60 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +/// @title MockOffchainAggregator +/// @notice This contract is a mock implementation of an offchain aggregator for testing purposes. +/// @dev This contract simulates the behavior of an offchain aggregator and allows for updating answers and round data. contract MockOffchainAggregator { + /// @notice The minimum possible answer the aggregator can report. int192 private constant MIN_ANSWER_POSSIBLE = 1; - int192 private constant MAX_ANSWER_POSSIBLE = 95780971304118053647396689196894323976171195136475135; // type(uint176).max + /// @notice The maximum possible answer the aggregator can report. + int192 private constant MAX_ANSWER_POSSIBLE = + 95780971304118053647396689196894323976171195136475135; // type(uint176).max + + /// @notice The number of decimals used by the aggregator. uint8 public decimals; + + /// @notice The latest answer reported by the aggregator. int256 public latestAnswer; + + /// @notice The timestamp of the latest answer. uint256 public latestTimestamp; + + /// @notice The latest round ID. uint256 public latestRound; - // Lowest answer the system is allowed to report in response to transmissions - // Not exposed from the Proxy contract + /// @notice The minimum answer the aggregator is allowed to report. int192 public minAnswer; - // Highest answer the system is allowed to report in response to transmissions - // Not exposed from the Proxy contract + + /// @notice The maximum answer the aggregator is allowed to report. int192 public maxAnswer; - mapping(uint256 => int256) public getAnswer; // gets answer for round + /// @notice Mapping to get the answer for a specific round ID. + mapping(uint256 => int256) public getAnswer; + + /// @notice Mapping to get the timestamp for a specific round ID. mapping(uint256 => uint256) public getTimestamp; + + /// @notice Mapping to get the start time for a specific round ID. mapping(uint256 => uint256) private getStartedAt; + /** + * @notice Constructor to initialize the MockOffchainAggregator contract with initial parameters. + * @param _decimals - The number of decimals for the aggregator. + * @param _initialAnswer - The initial answer to be set in the mock aggregator. + */ constructor(uint8 _decimals, int256 _initialAnswer) { decimals = _decimals; updateAnswer(_initialAnswer); - // If the minAnswer has a value of 1 and the maxAnswer has a value of 95780971304118053647396689196894323976171195136475135 then that theoretically means there is no min or max for that feed - // If the minAnswer and maxAnswer values are set to other than those mentioned above, then there are actually min and max for that feed - which you will need to normalize using the demicals value minAnswer = MIN_ANSWER_POSSIBLE; maxAnswer = MAX_ANSWER_POSSIBLE; } + /** + * @notice Updates the answer in the mock aggregator. + * @param _answer - The new answer to be set. + */ function updateAnswer(int256 _answer) public { latestAnswer = _answer; latestTimestamp = block.timestamp; @@ -39,7 +64,19 @@ contract MockOffchainAggregator { getStartedAt[latestRound] = block.timestamp; } - function updateRoundData(uint80 _roundId, int256 _answer, uint256 _timestamp, uint256 _startedAt) public { + /** + * @notice Updates the round data in the mock aggregator. + * @param _roundId - The round ID to be updated. + * @param _answer - The new answer to be set. + * @param _timestamp - The timestamp to be set. + * @param _startedAt - The timestamp when the round started. + */ + function updateRoundData( + uint80 _roundId, + int256 _answer, + uint256 _timestamp, + uint256 _startedAt + ) public { latestRound = _roundId; latestAnswer = _answer; latestTimestamp = _timestamp; @@ -48,18 +85,55 @@ contract MockOffchainAggregator { getStartedAt[latestRound] = _startedAt; } - function getRoundData(uint80 _roundId) + /** + * @notice Gets the round data for a specific round ID. + * @param _roundId - The round ID to get the data for. + * @return roundId - The round ID. + * @return answer - The answer for the round. + * @return startedAt - The timestamp when the round started. + * @return updatedAt - The timestamp when the round was updated. + * @return answeredInRound - The round ID in which the answer was computed. + */ + function getRoundData( + uint80 _roundId + ) external view - returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) { - return (_roundId, getAnswer[_roundId], getStartedAt[_roundId], getTimestamp[_roundId], _roundId); + return ( + _roundId, + getAnswer[_roundId], + getStartedAt[_roundId], + getTimestamp[_roundId], + _roundId + ); } + /** + * @notice Gets the latest round data. + * @return roundId - The latest round ID. + * @return answer - The latest answer. + * @return startedAt - The timestamp when the latest round started. + * @return updatedAt - The timestamp when the latest round was updated. + * @return answeredInRound - The round ID in which the latest answer was computed. + */ function latestRoundData() external view - returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) { return ( uint80(latestRound), @@ -70,8 +144,19 @@ contract MockOffchainAggregator { ); } - function updateMinAndMaxAnswers(int192 _minAnswer, int192 _maxAnswer) external { - require(_minAnswer < _maxAnswer, "minAnswer must be less than maxAnswer"); + /** + * @notice Updates the minimum and maximum answers the aggregator can report. + * @param _minAnswer - The new minimum answer. + * @param _maxAnswer - The new maximum answer. + */ + function updateMinAndMaxAnswers( + int192 _minAnswer, + int192 _maxAnswer + ) external { + require( + _minAnswer < _maxAnswer, + "minAnswer must be less than maxAnswer" + ); require(_minAnswer >= MIN_ANSWER_POSSIBLE, "minAnswer is too low"); require(_maxAnswer <= MAX_ANSWER_POSSIBLE, "maxAnswer is too high"); diff --git a/src/data-feeds/MockV3Aggregator.sol b/src/data-feeds/MockV3Aggregator.sol index 1e979af..27661a0 100644 --- a/src/data-feeds/MockV3Aggregator.sol +++ b/src/data-feeds/MockV3Aggregator.sol @@ -1,82 +1,179 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {AggregatorV2V3Interface} from "./interfaces/AggregatorV2V3Interface.sol"; +import {AggregatorInterface, AggregatorV3Interface, AggregatorV2V3Interface} from "./interfaces/AggregatorV2V3Interface.sol"; import {MockOffchainAggregator} from "./MockOffchainAggregator.sol"; +/// @title MockV3Aggregator +/// @notice This contract is a mock implementation of the AggregatorV2V3Interface for testing purposes. +/// @dev This contract interacts with a MockOffchainAggregator to simulate price feeds. contract MockV3Aggregator is AggregatorV2V3Interface { + /// @notice The version of the aggregator. uint256 public constant override version = 0; + /// @notice The address of the current aggregator. address public aggregator; + + /// @notice The address of the proposed aggregator. address public proposedAggregator; + /** + * @notice Constructor to initialize the MockV3Aggregator contract with initial parameters. + * @param _decimals - The number of decimals for the aggregator. + * @param _initialAnswer - The initial answer to be set in the mock aggregator. + */ constructor(uint8 _decimals, int256 _initialAnswer) { - aggregator = address(new MockOffchainAggregator(_decimals, _initialAnswer)); + aggregator = address( + new MockOffchainAggregator(_decimals, _initialAnswer) + ); proposedAggregator = address(0); } + /** + * @inheritdoc AggregatorV3Interface + */ function decimals() external view override returns (uint8) { return AggregatorV2V3Interface(aggregator).decimals(); } - function getAnswer(uint256 roundId) external view override returns (int256) { + /** + * @inheritdoc AggregatorInterface + */ + function getAnswer( + uint256 roundId + ) external view override returns (int256) { return AggregatorV2V3Interface(aggregator).getAnswer(roundId); } - function getRoundData(uint80 _roundId) + /** + * @inheritdoc AggregatorV3Interface + */ + function getRoundData( + uint80 _roundId + ) external view override - returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) { return AggregatorV2V3Interface(aggregator).getRoundData(_roundId); } + /** + * @inheritdoc AggregatorV3Interface + */ function latestRoundData() external view override - returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) { return AggregatorV2V3Interface(aggregator).latestRoundData(); } - function getTimestamp(uint256 roundId) external view override returns (uint256) { + /** + * @inheritdoc AggregatorInterface + */ + function getTimestamp( + uint256 roundId + ) external view override returns (uint256) { return AggregatorV2V3Interface(aggregator).getTimestamp(roundId); } + /** + * @inheritdoc AggregatorInterface + */ function latestAnswer() external view override returns (int256) { return AggregatorV2V3Interface(aggregator).latestAnswer(); } + /** + * @inheritdoc AggregatorInterface + */ function latestTimestamp() external view override returns (uint256) { return AggregatorV2V3Interface(aggregator).latestTimestamp(); } + /** + * @inheritdoc AggregatorInterface + */ function latestRound() external view override returns (uint256) { return AggregatorV2V3Interface(aggregator).latestRound(); } + /** + * @notice Updates the answer in the mock aggregator. + * @param _answer - The new answer to be set. + */ function updateAnswer(int256 _answer) public { MockOffchainAggregator(aggregator).updateAnswer(_answer); } - function updateRoundData(uint80 _roundId, int256 _answer, uint256 _timestamp, uint256 _startedAt) public { - MockOffchainAggregator(aggregator).updateRoundData(_roundId, _answer, _timestamp, _startedAt); + /** + * @notice Updates the round data in the mock aggregator. + * @param _roundId - The round ID to be updated. + * @param _answer - The new answer to be set. + * @param _timestamp - The timestamp to be set. + * @param _startedAt - The timestamp when the round started. + */ + function updateRoundData( + uint80 _roundId, + int256 _answer, + uint256 _timestamp, + uint256 _startedAt + ) public { + MockOffchainAggregator(aggregator).updateRoundData( + _roundId, + _answer, + _timestamp, + _startedAt + ); } + /** + * @notice Proposes a new aggregator. + * @param _aggregator - The address of the proposed aggregator. + */ function proposeAggregator(AggregatorV2V3Interface _aggregator) external { - require(address(_aggregator) != address(0), "Proposed aggregator cannot be zero address"); - require(address(_aggregator) != aggregator, "Proposed aggregator cannot be current aggregator"); + require( + address(_aggregator) != address(0), + "Proposed aggregator cannot be zero address" + ); + require( + address(_aggregator) != aggregator, + "Proposed aggregator cannot be current aggregator" + ); proposedAggregator = address(_aggregator); } + /** + * @notice Confirms the proposed aggregator. + * @param _aggregator - The address of the proposed aggregator. + */ function confirmAggregator(address _aggregator) external { - require(_aggregator == address(proposedAggregator), "Invalid proposed aggregator"); + require( + _aggregator == address(proposedAggregator), + "Invalid proposed aggregator" + ); aggregator = proposedAggregator; proposedAggregator = address(0); } + /** + * @inheritdoc AggregatorV3Interface + */ function description() external pure override returns (string memory) { return "src/data-feeds/MockV3Aggregator.sol"; } diff --git a/src/data-feeds/interfaces/AggregatorInterface.sol b/src/data-feeds/interfaces/AggregatorInterface.sol index 37491d4..07d76b1 100644 --- a/src/data-feeds/interfaces/AggregatorInterface.sol +++ b/src/data-feeds/interfaces/AggregatorInterface.sol @@ -1,18 +1,63 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +/// @title AggregatorInterface +/// @notice Interface for accessing data from an aggregator contract. +/// @dev Provides methods to get the latest data and historical data for specific rounds. interface AggregatorInterface { + /** + * @notice Gets the latest answer from the aggregator. + * @return int256 - The latest answer. + */ function latestAnswer() external view returns (int256); + /** + * @notice Gets the timestamp of the latest answer from the aggregator. + * @return uint256 - The timestamp of the latest answer. + */ function latestTimestamp() external view returns (uint256); + /** + * @notice Gets the latest round ID from the aggregator. + * @return uint256 - The latest round ID. + */ function latestRound() external view returns (uint256); + /** + * @notice Gets the answer for a specific round ID. + * @param roundId - The round ID to get the answer for. + * @return int256 - The answer for the given round ID. + */ function getAnswer(uint256 roundId) external view returns (int256); + /** + * @notice Gets the timestamp for a specific round ID. + * @param roundId - The round ID to get the timestamp for. + * @return uint256 - The timestamp for the given round ID. + */ function getTimestamp(uint256 roundId) external view returns (uint256); - event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); + /** + * @notice Emitted when the answer is updated. + * @param current - The updated answer. + * @param roundId - The round ID for which the answer was updated. + * @param updatedAt - The timestamp when the answer was updated. + */ + event AnswerUpdated( + int256 indexed current, + uint256 indexed roundId, + uint256 updatedAt + ); - event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt); + /** + * @notice Emitted when a new round is started. + * @param roundId - The round ID of the new round. + * @param startedBy - The address of the account that started the round. + * @param startedAt - The timestamp when the round was started. + */ + event NewRound( + uint256 indexed roundId, + address indexed startedBy, + uint256 startedAt + ); } diff --git a/src/data-feeds/interfaces/AggregatorV2V3Interface.sol b/src/data-feeds/interfaces/AggregatorV2V3Interface.sol index c023e3d..9a046b6 100644 --- a/src/data-feeds/interfaces/AggregatorV2V3Interface.sol +++ b/src/data-feeds/interfaces/AggregatorV2V3Interface.sol @@ -4,4 +4,11 @@ pragma solidity ^0.8.0; import {AggregatorInterface} from "./AggregatorInterface.sol"; import {AggregatorV3Interface} from "./AggregatorV3Interface.sol"; -interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {} +/// @title AggregatorV2V3Interface +/// @notice Interface that inherits from both AggregatorInterface and AggregatorV3Interface. +interface AggregatorV2V3Interface is + AggregatorInterface, + AggregatorV3Interface +{ + +} diff --git a/src/data-feeds/interfaces/AggregatorV3Interface.sol b/src/data-feeds/interfaces/AggregatorV3Interface.sol index 2fe085b..987dbf5 100644 --- a/src/data-feeds/interfaces/AggregatorV3Interface.sol +++ b/src/data-feeds/interfaces/AggregatorV3Interface.sol @@ -1,23 +1,68 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +/// @title AggregatorV3Interface +/// @notice Interface for accessing detailed data from an aggregator contract, including round data and metadata. +/// @dev Provides methods to get the latest data, historical data for specific rounds, and metadata such as decimals and description. interface AggregatorV3Interface { + /** + * @notice Gets the number of decimals used by the aggregator. + * @return uint8 - The number of decimals. + */ function decimals() external view returns (uint8); + /** + * @notice Gets the description of the aggregator. + * @return string memory - The description of the aggregator. + */ function description() external view returns (string memory); + /** + * @notice Gets the version of the aggregator. + * @return uint256 - The version of the aggregator. + */ function version() external view returns (uint256); - // getRoundData and latestRoundData should both raise "No data present" - // if they do not have data to report, instead of returning unset values - // which could be misinterpreted as actual reported values. - function getRoundData(uint80 _roundId) + /** + * @notice Gets the round data for a specific round ID. + * @param _roundId - The round ID to get the data for. + * @return roundId - The round ID. + * @return answer - The answer for the round. + * @return startedAt - The timestamp when the round started. + * @return updatedAt - The timestamp when the round was updated. + * @return answeredInRound - The round ID in which the answer was computed. + * @dev This function should raise "No data present" if no data is available for the given round ID. + */ + function getRoundData( + uint80 _roundId + ) external view - returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ); + /** + * @notice Gets the latest round data. + * @return roundId - The latest round ID. + * @return answer - The latest answer. + * @return startedAt - The timestamp when the latest round started. + * @return updatedAt - The timestamp when the latest round was updated. + * @return answeredInRound - The round ID in which the latest answer was computed. + * @dev This function should raise "No data present" if no data is available. + */ function latestRoundData() external view - returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ); } diff --git a/src/shared/LinkToken.sol b/src/shared/LinkToken.sol index 7375d1b..9887c3b 100644 --- a/src/shared/LinkToken.sol +++ b/src/shared/LinkToken.sol @@ -3,19 +3,31 @@ pragma solidity ^0.8.19; import {ERC677} from "@chainlink/contracts-ccip/src/v0.8/shared/token/ERC677/ERC677.sol"; +/// @title LinkToken +/// @notice This contract implements the ChainLink Token (LINK) using the ERC677 standard. +/// @dev Inherits from the ERC677 token contract and initializes with a fixed total supply and standard token details. contract LinkToken is ERC677 { + /// @notice The total supply of LINK tokens. uint private constant TOTAL_SUPPLY = 10 ** 27; + + /// @notice The name of the LINK token. string private constant NAME = "ChainLink Token"; + + /// @notice The symbol of the LINK token. string private constant SYMBOL = "LINK"; + /** + * @notice Constructor to initialize the LinkToken contract with a fixed total supply, name, and symbol. + * @dev Calls the ERC677 constructor with the name and symbol, and then mints the total supply to the contract deployer. + */ constructor() ERC677(NAME, SYMBOL) { _onCreate(); } /** - * @dev Hook that is called when this contract is created. - * Useful to override constructor behaviour in child contracts (e.g., LINK bridge tokens). - * @notice Default implementation mints 10**27 tokens to msg.sender + * @notice Hook that is called when this contract is created. + * @dev Useful to override constructor behaviour in child contracts (e.g., LINK bridge tokens). + * The default implementation mints 10**27 tokens to the contract deployer. */ function _onCreate() internal virtual { _mint(msg.sender, TOTAL_SUPPLY);