diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4336d667a4..3e27701b0b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,9 +33,9 @@ For example, `feat(scope): description of feature` should only impact the `scope Follow the [NatSpec format](https://docs.soliditylang.org/en/latest/natspec-format.html) for documenting smart contract source code. Please adhere to a few additional standards: -#### Multi-line comments +#### Comment style -Choose `/** */` over `///` for multi-line NatSpec comments to save column space. +Choose `///` over `/** */` for multi-line NatSpec comments for consistency. All NatSpec comments should use `///` instead of `/** */`. Additional explanatory comments should use `//`, even for multi-line comments. #### Notice tag @@ -152,6 +152,64 @@ struct Some { } ``` +#### Mentioning other files in the repo + +To mention another contract file in the repo use the standard like this: + +```solidity +/// @notice See the documentation in {IProverPool} +``` + +If you are referring to some struct or function within the file you can use the standard like this: + +```solidity +/// @notice See the struct in {TaikoData.Config} +``` + +#### Documenting interfaces + +To document the implementing contract of an interface, you cannot use `@inheritdoc`, it is not supported for contracts. Thus, you should mention a statement like so: + +```solidity +/// @notice See the documentation in {IProverPool} +``` + +You can then mention implementation specific details by adding a `@dev` tag: + +```solidity +/// @notice See the documentation in {IProverPool} +/// @dev This implementation uses a ProverPool of size 32. +``` + +#### Documenting internal functions and structs + +Internal functions and structs should commented with a `@dev` tag, and you can also comment the contents of the struct with explanatory comments. + +#### Documenting user-facing functions versus internal functions + +All user-facing functions should be fully documented with NatSpec. Internal functions should always be commented with a `@dev` tag, not a `@notice` tag. + +#### Explanatory comments + +Explanatory comments use `//`. There is a common idea that the code describes the documentation. There are pros to this approach. One of the pros is that you remove the coupling between documentation and the code it's describing, that's why we should always strive for the [minimum viable documentation](https://google.github.io/styleguide/docguide/best_practices.html#minimum-viable-documentation) (one of our core documentation [philosophies](#philosophies)). It can also appear cleaner. + +It's important that our codebase is well documented with **explanatory comments**. Thus, in addition to the standard NatSpec documentation which we should apply, we should comment the more complex things in our codebase for higher readability. More important than commenting _what_ we should be concerned with commenting _why_. The _what_ does not need to be commented for obvious things, of course the code is able to achieve that. We should comment the _what_ for more complex things to aid in the reader for more quickly understanding the code. In addition to that, we should strive to answer the _why_ with comments in our code. + +Keep in mind the advantage of having minimum viable documentation. Keep the comments close to the code which it is describing, so that it does not easily go stale or out of date. + +#### Annotation ordering + +There are several annotations used in NatSpec, this is the order of precedence we use from top to bottom: + +- @title +- @author [we don't use this tag] +- @notice +- @dev +- @param +- @return +- @inheritdoc +- @custom [we don't use this tag unless we define the convention for it here] + ## Documentation standards This section describes our documentation standards at Taiko. diff --git a/packages/protocol/contracts/L1/IProofVerifier.sol b/packages/protocol/contracts/L1/IProofVerifier.sol index 5de6b41c2e..b7c2a89d9e 100644 --- a/packages/protocol/contracts/L1/IProofVerifier.sol +++ b/packages/protocol/contracts/L1/IProofVerifier.sol @@ -6,20 +6,15 @@ pragma solidity ^0.8.20; -/** - * @title IProofVerifier Interface - * @dev Interface for the ProofVerifier contract which is responsible for - * verifying proofs. - */ +/// @title IProofVerifier +/// @notice Contract that is responsible for verifying proofs. interface IProofVerifier { - /** - * @notice Verify proof(s) for the given block. - * This function should revert if the verification fails. - * - * @param blockId Unique identifier for the block. - * @param blockProofs Raw bytes representing the proof(s). - * @param instance Hash combining evidence and configuration data. - */ + /// @notice Verify the given proof(s) for the given blockId. This function + /// should revert if the verification fails. + /// @param blockId Unique identifier for the block. + /// @param blockProofs Raw bytes representing the proof(s). + /// @param instance Hashed evidence & config data. If set to zero, proof is + /// assumed to be from oracle/system prover. function verifyProofs( uint256 blockId, bytes calldata blockProofs, diff --git a/packages/protocol/contracts/L1/IProverPool.sol b/packages/protocol/contracts/L1/IProverPool.sol index 0c43c44341..59b7ff3f07 100644 --- a/packages/protocol/contracts/L1/IProverPool.sol +++ b/packages/protocol/contracts/L1/IProverPool.sol @@ -6,20 +6,16 @@ pragma solidity ^0.8.20; -/** - * @title IProverPool Interface - * @dev Interface for the ProverPool contract, which manages the assignment, - * release, and slashing of provers. - */ +/// @title IProverPool +/// @notice Interface which manages the assignment, release, and slashing of +/// provers. This pool is where the protocol selects provers from to prove L1 +/// block validity. interface IProverPool { - /** - * @notice Assigns a prover to a specific block. - * - * @param blockId Unique identifier for the block. - * @param feePerGas The fee amount per unit of gas. - * @return prover Address of the assigned prover. - * @return rewardPerGas Reward allocated per unit of gas for the prover. - */ + /// @notice Assigns a prover to a specific block. + /// @param blockId Unique identifier for the block. + /// @param feePerGas The fee amount per unit of gas. + /// @return prover Address of the assigned prover. + /// @return rewardPerGas Reward allocated per unit of gas for the prover. function assignProver( uint64 blockId, uint32 feePerGas @@ -27,21 +23,15 @@ interface IProverPool { external returns (address prover, uint32 rewardPerGas); - /** - * @notice Releases a prover. - * - * @param prover Address of the prover to be released. - */ + /// @notice Releases a prover. + /// @param prover Address of the prover to be released. function releaseProver(address prover) external; - /** - * @notice Penalizes a prover by burning their staked tokens. - * - * @param blockId Unique identifier for the block associated with the - * prover's task. - * @param prover Address of the prover being penalized. - * @param proofReward Reward initially allocated for proof validation. - */ + /// @notice Penalizes a prover by burning their staked tokens. + /// @param blockId Unique identifier for the block associated with the + /// prover's task. + /// @param prover Address of the prover being penalized. + /// @param proofReward Reward initially allocated for proof validation. function slashProver( uint64 blockId, address prover, diff --git a/packages/protocol/contracts/L1/ProofVerifier.sol b/packages/protocol/contracts/L1/ProofVerifier.sol index e2db4229c1..c91eb975a6 100644 --- a/packages/protocol/contracts/L1/ProofVerifier.sol +++ b/packages/protocol/contracts/L1/ProofVerifier.sol @@ -13,33 +13,24 @@ import { LibZKPVerifier } from "./libs/verifiers/LibZKPVerifier.sol"; import { IProofVerifier } from "./IProofVerifier.sol"; import { LibBytesUtils } from "../thirdparty/LibBytesUtils.sol"; -/** - * @title ProofVerifier - * @dev Contract for verifying proofs in the rollup. - */ +/// @title ProofVerifier +/// @notice See the documentation in {IProofVerifier}. contract ProofVerifier is EssentialContract, IProofVerifier { uint256[50] private __gap; error L1_INVALID_PROOF(); - /** - * @notice Initializes the contract with the provided address manager. - * @param _addressManager The address of the address manager contract. - */ + /// @notice Initializes the contract with the provided address manager. + /// @param _addressManager The address of the address manager contract. function init(address _addressManager) external initializer { EssentialContract._init(_addressManager); } - /** - * @notice Verifies the provided proofs. - * @dev Throws an error if verification fails. - * - * @param blockProofs Raw bytes of proof(s). - * @param instance Hashed evidence & config data. If set to zero, proof is - * assumed to be from oracle/system prover. - */ + /// @inheritdoc IProofVerifier function verifyProofs( - uint256, /*blockId*/ + // blockId is unused now, but can be used later when supporting + // different types of proofs. + uint256, bytes calldata blockProofs, bytes32 instance ) @@ -79,8 +70,6 @@ contract ProofVerifier is EssentialContract, IProofVerifier { } } -/** - * @title ProxiedProofVerifier - * @dev Proxied version of the ProofVerifier contract. - */ +/// @title ProxiedProofVerifier +/// @notice Proxied version of the ProofVerifier contract. contract ProxiedProofVerifier is Proxied, ProofVerifier { } diff --git a/packages/protocol/contracts/L1/ProverPool.sol b/packages/protocol/contracts/L1/ProverPool.sol index d739173978..12f98f8fd9 100644 --- a/packages/protocol/contracts/L1/ProverPool.sol +++ b/packages/protocol/contracts/L1/ProverPool.sol @@ -13,14 +13,8 @@ import { LibMath } from "../libs/LibMath.sol"; import { TaikoToken } from "./TaikoToken.sol"; import { Proxied } from "../common/Proxied.sol"; -/** - * @title ProverPool - * @notice This contract manages a pool of the top 32 provers. This pool is - * where the protocol selects provers from to prove L1 block validity. There are - * two actors: - * - Provers (generating the proofs) - * - Stakers (staking tokens for the provers) - */ +/// @title ProverPool +/// @notice See the documentation in {IProverPool}. contract ProverPool is EssentialContract, IProverPool { using LibMath for uint256; @@ -83,23 +77,18 @@ contract ProverPool is EssentialContract, IProverPool { _; } - /** - * @notice Initializes the ProverPool contract. - * @param _addressManager Address of the contract that manages proxy - * addresses. - */ + /// @notice Initializes the ProverPool contract. + /// @param _addressManager Address of the contract that manages proxy. function init(address _addressManager) external initializer { EssentialContract._init(_addressManager); } - /** - * @notice Protocol specifies the current feePerGas and assigns a prover to - * a block. - * @param blockId The block id. - * @param feePerGas The current fee per gas. - * @return prover The address of the assigned prover. - * @return rewardPerGas The reward per gas for the assigned prover. - */ + /// @notice Protocol specifies the current feePerGas and assigns a prover to + /// a block. + /// @param blockId The block id. + /// @param feePerGas The current fee per gas. + /// @return prover The address of the assigned prover. + /// @return rewardPerGas The reward per gas for the assigned prover. function assignProver( uint64 blockId, uint32 feePerGas @@ -116,21 +105,19 @@ contract ProverPool is EssentialContract, IProverPool { bytes32 rand = keccak256(abi.encode(blockhash(block.number - 1), blockId)); - uint256 id = _selectProver(rand, weights); + uint256 proverId = _selectProver(rand, weights); - if (id == 0) { + if (proverId == 0) { return (address(0), 0); } else { - provers[id].currentCapacity -= 1; - return (proverIdToAddress[id], erpg[id - 1]); + provers[proverId].currentCapacity -= 1; + return (proverIdToAddress[proverId], erpg[proverId - 1]); } } } - /** - * @notice Increases the capacity of the prover by releasing a prover. - * @param addr The address of the prover to release. - */ + /// @notice Increases the capacity of the prover by releasing a prover. + /// @param addr The address of the prover to release. function releaseProver(address addr) external onlyFromProtocol { (Staker memory staker, Prover memory prover) = getStaker(addr); @@ -142,12 +129,10 @@ contract ProverPool is EssentialContract, IProverPool { } } - /** - * @notice Slashes a prover. - * @param addr The address of the prover to slash. - * @param blockId The block id of the slashing event. - * @param proofReward The reward for providing the proof. - */ + /// @notice Slashes a prover. + /// @param addr The address of the prover to slash. + /// @param blockId The block id of the block which was not proved in time. + /// @param proofReward The reward that was set for the block's proof. function slashProver( uint64 blockId, address addr, @@ -189,12 +174,11 @@ contract ProverPool is EssentialContract, IProverPool { } } - /** - * @notice Stakes tokens for a prover in the pool. - * @param amount The amount of Taiko tokens to stake. - * @param rewardPerGas The expected reward per gas for the prover. - * @param maxCapacity The maximum number of blocks that a prover can handle. - */ + /// @notice Stakes tokens for a prover in the pool. + /// @param amount The amount of Taiko tokens to stake. + /// @param rewardPerGas The expected reward per gas for the prover. + /// @param maxCapacity The maximum number of blocks that a prover can + /// handle. function stake( uint64 amount, uint32 rewardPerGas, @@ -215,29 +199,23 @@ contract ProverPool is EssentialContract, IProverPool { } } - /** - * @notice Request an exit for the staker. This will withdraw the staked - * tokens and exit the prover from the pool. - */ + /// @notice Requests an exit for the staker. This will withdraw the staked + /// tokens and exit the prover from the pool. function exit() external nonReentrant { _withdraw(msg.sender); _exit(msg.sender, true); } - /** - * @notice Withdraws staked tokens back from a matured exit. - */ + /// @notice Withdraws staked tokens back from a matured exit. function withdraw() external nonReentrant { if (!_withdraw(msg.sender)) revert NO_MATURE_EXIT(); } - /** - * @notice Retrieves the information of a staker and their corresponding - * prover using their address. - * @param addr The address of the staker. - * @return staker The staker's information. - * @return prover The prover's information. - */ + /// @notice Retrieves the information of a staker and their corresponding + /// prover using their address. + /// @param addr The address of the staker. + /// @return staker The staker's information. + /// @return prover The prover's information. function getStaker(address addr) public view @@ -251,10 +229,8 @@ contract ProverPool is EssentialContract, IProverPool { } } - /** - * @notice Calculates and returns the current total capacity of the pool. - * @return capacity The total capacity of the pool. - */ + /// @notice Calculates and returns the current total capacity of the pool. + /// @return capacity The total capacity of the pool. function getCapacity() public view returns (uint256 capacity) { unchecked { for (uint256 i = 1; i <= MAX_NUM_PROVERS; ++i) { @@ -263,12 +239,10 @@ contract ProverPool is EssentialContract, IProverPool { } } - /** - * @notice Retrieves the current active provers and their corresponding - * stakers. - * @return _provers The active provers. - * @return _stakers The stakers of the active provers. - */ + /// @notice Retrieves the current active provers and their corresponding + /// stakers. + /// @return _provers The active provers. + /// @return _stakers The stakers of the active provers. function getProvers() public view @@ -282,13 +256,11 @@ contract ProverPool is EssentialContract, IProverPool { } } - /** - * @notice Returns the current active provers and their weights. - * @param feePerGas The protocol's current fee per gas. - * @return weights The weights of the current provers in the pool. - * @return erpg The effective reward per gas of the current provers in the - * pool. This is smoothed out to be in range of the current fee per gas. - */ + /// @notice Retrieves the current active provers and their weights. + /// @param feePerGas The protocol's current fee per gas. + /// @return weights The weights of the current provers in the pool. + /// @return erpg The effective reward per gas of the current provers in the + /// pool. This is smoothed out to be in range of the current fee per gas. function getProverWeights(uint32 feePerGas) public view @@ -310,12 +282,15 @@ contract ProverPool is EssentialContract, IProverPool { } else { erpg[i] = _prover.rewardPerGas; } + // Calculates the prover's weight based on the staked amount + // and effective rewardPerGas weights[i] = _calcWeight(_prover.stakedAmount, erpg[i]); } } } } + /// @dev See the documentation for the callers of this internal function. function _stake( address addr, uint64 amount, @@ -383,7 +358,7 @@ contract ProverPool is EssentialContract, IProverPool { emit Staked(addr, amount, rewardPerGas, maxCapacity); } - // Perform a full exit for the given address + /// @dev See the documentation for the callers of this internal function. function _exit(address addr, bool checkExitTimestamp) private { Staker storage staker = stakers[addr]; if (staker.proverId == 0) return; @@ -393,7 +368,7 @@ contract ProverPool is EssentialContract, IProverPool { delete proverIdToAddress[staker.proverId]; // Delete the prover but make it non-zero for cheaper rewrites - // by keep rewardPerGas = 1 + // by keeping rewardPerGas = 1 provers[staker.proverId] = Prover(0, 1, 0); // Clear data if there is an 'exit' anyway, regardless of @@ -412,6 +387,10 @@ contract ProverPool is EssentialContract, IProverPool { emit Exited(addr, staker.exitAmount); } + /// @dev See the documentation for the callers of this internal function. + /// @param addr The address of the staker to withdraw. This is where the + /// staked tokens are sent. + /// @return success Whether the withdrawal is successful. function _withdraw(address addr) private returns (bool success) { Staker storage staker = stakers[addr]; if ( @@ -431,7 +410,10 @@ contract ProverPool is EssentialContract, IProverPool { return true; } - // Calculates the user weight's when it stakes/unstakes/slashed + /// @dev See the documentation for the callers of this internal function. + /// @param stakedAmount The staked amount of the prover. + /// @param rewardPerGas The reward per gas of the prover. + /// @return weight The weight of the prover (essentially a "score"). function _calcWeight( uint64 stakedAmount, uint32 rewardPerGas @@ -443,13 +425,20 @@ contract ProverPool is EssentialContract, IProverPool { if (rewardPerGas == 0) { return 0; } - + // The weight has a direct linear relationship to the staked amount and + // an inverse square relationship to the rewardPerGas. weight = stakedAmount / rewardPerGas / rewardPerGas; if (weight == 0) { weight = 1; } } + /// @dev See the documentation for the callers of this internal function. + /// This function will select a prover and those that have a higher weight + /// are more likely to be selected. + /// @param rand A random input used as a seed. + /// @param weights An array of the weights of the provers. + /// @return proverId The selected prover id. function _selectProver( bytes32 rand, uint256[MAX_NUM_PROVERS] memory weights @@ -460,13 +449,18 @@ contract ProverPool is EssentialContract, IProverPool { { unchecked { uint256 totalWeight; + // Calculate the total weight for (uint256 i; i < MAX_NUM_PROVERS; ++i) { totalWeight += weights[i]; } + // If the weight is 0 select the first prover if (totalWeight == 0) return 0; - + // Select a random number in the range [0, totalWeight) uint256 r = uint256(rand) % totalWeight; uint256 accumulatedWeight; + // Go through each prover and check if the random number is in range + // of the accumulatedWeight. The probability of a prover being + // selected is proportional to its weight. for (uint256 i; i < MAX_NUM_PROVERS; ++i) { accumulatedWeight += weights[i]; if (r < accumulatedWeight) { @@ -478,8 +472,6 @@ contract ProverPool is EssentialContract, IProverPool { } } -/** - * @title ProxiedProverPool - * @dev Proxied version of the ProverPool contract. - */ +/// @title ProxiedProverPool +/// @notice Proxied version of the ProverPool contract. contract ProxiedProverPool is Proxied, ProverPool { } diff --git a/packages/protocol/contracts/L1/TaikoConfig.sol b/packages/protocol/contracts/L1/TaikoConfig.sol index 12175b9c3e..e926f1f89f 100644 --- a/packages/protocol/contracts/L1/TaikoConfig.sol +++ b/packages/protocol/contracts/L1/TaikoConfig.sol @@ -8,85 +8,41 @@ pragma solidity ^0.8.20; import { TaikoData } from "../L1/TaikoData.sol"; -/** - * @title TaikoConfig - Library for retrieving Taiko configuration parameters - * @notice This library provides functions to access various configuration - * parameters used in Taiko contracts. - */ +/// @title TaikoConfig +/// @notice This library provides functions to access various configuration +/// parameters used in Taiko contracts. library TaikoConfig { - /** - * @dev Retrieves the Taiko configuration parameters. - * @return config The Taiko configuration object containing various - * configuration values. - */ + /// @dev See {TaikoData.Config} for explanations of each parameter. + /// @return config The Taiko configuration object containing various + /// configuration values. function getConfig() internal pure returns (TaikoData.Config memory) { return TaikoData.Config({ - // Group 1: General Configurations - // The chain ID of the network where Taiko contracts are deployed. chainId: 167_006, - // Flag indicating whether the relay signal root is enabled or not. relaySignalRoot: false, - // -------------------------------------------------------- - // Group 2: Block-Level Configurations - // The maximum number of proposals allowed in a single block. blockMaxProposals: 403_200, - // The size of the block ring buffer, allowing extra space for - // proposals. blockRingBufferSize: 403_210, - // The maximum number of verifications allowed per transaction in a - // block. + // This number is calculated from blockMaxProposals to make the + // maximum value of the multiplier close to 20.0 blockMaxVerificationsPerTx: 10, - // The maximum gas limit allowed per block. blockMaxGasLimit: 6_000_000, - // The base gas for processing a block. blockFeeBaseGas: 20_000, - // The maximum number of transactions allowed in a single block. blockMaxTransactions: 79, - // The maximum allowed bytes for the proposed transaction list - // calldata. blockMaxTxListBytes: 120_000, - // The expiration time for the block transaction list. blockTxListExpiry: 0, - // -------------------------------------------------------- - // Group 3: Proof-Related Configurations - // The cooldown period for regular proofs (in minutes). proofRegularCooldown: 30 minutes, - // The cooldown period for oracle proofs (in minutes). proofOracleCooldown: 15 minutes, - // The minimum time window allowed for a proof submission (in - // minutes). proofMinWindow: 10 minutes, - // The maximum time window allowed for a proof submission (in - // minutes). proofMaxWindow: 90 minutes, - // The window multiplier used to calculate proof time windows (in - // percentage). proofWindowMultiplier: 200, // 200% - // -------------------------------------------------------- - // Group 4: Ethereum Deposit Related Configurations - // The size of the Ethereum deposit ring buffer. ethDepositRingBufferSize: 1024, - // The minimum number of Ethereum deposits allowed per block. ethDepositMinCountPerBlock: 8, - // The maximum number of Ethereum deposits allowed per block. ethDepositMaxCountPerBlock: 32, - // The minimum amount of Ethereum required for a deposit. ethDepositMinAmount: 1 ether, - // The maximum amount of Ethereum allowed for a deposit. ethDepositMaxAmount: 10_000 ether, - // The gas cost for processing an Ethereum deposit. ethDepositGas: 21_000, - // The maximum fee allowed for an Ethereum deposit. ethDepositMaxFee: 1 ether / 10, - // -------------------------------------------------------- - // Group 5: Tokenomics - // The multiplier for calculating rewards for an open proposal (in - // percentage). rewardOpenMultipler: 150, // 150% - // The maximum count of open proposals considered for rewards - // calculation. rewardOpenMaxCount: 201_600, // blockMaxProposals / 2, - // The maximum penalty for delaying rewards (in basis points). rewardMaxDelayPenalty: 250 // 250 bps }); } diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index bdf4cf60bb..9c2ebcdb8c 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -6,44 +6,84 @@ pragma solidity ^0.8.20; +/// @title TaikoData +/// @notice This library defines various data structures used in the Taiko +/// protocol. library TaikoData { - // Struct holding Taiko configuration parameters + /// @dev Struct holding Taiko configuration parameters. See {TaikoConfig}. struct Config { - // Group 1: general configs + // --------------------------------------------------------------------- + // Group 1: General configs + // --------------------------------------------------------------------- + // The chain ID of the network where Taiko contracts are deployed. uint256 chainId; + // Flag indicating whether the relay signal root is enabled or not. bool relaySignalRoot; - // Group 2: block level configs + // --------------------------------------------------------------------- + // Group 2: Block level configs + // --------------------------------------------------------------------- + // The maximum number of proposals allowed in a single block. uint256 blockMaxProposals; + // Size of the block ring buffer, allowing extra space for proposals. uint256 blockRingBufferSize; - // This number is calculated from blockMaxProposals to make - // the 'the maximum value of the multiplier' close to 20.0 + // The maximum number of verifications allowed per transaction in a + // block. uint256 blockMaxVerificationsPerTx; + // The maximum gas limit allowed for a block. uint32 blockMaxGasLimit; + // The base gas for processing a block. uint32 blockFeeBaseGas; + // The maximum number of transactions allowed in a single block. uint64 blockMaxTransactions; + // The maximum allowed bytes for the proposed transaction list calldata. uint64 blockMaxTxListBytes; + // The expiration time for the block transaction list. uint256 blockTxListExpiry; - // Group 3: proof related configs + // --------------------------------------------------------------------- + // Group 3: Proof related configs + // --------------------------------------------------------------------- + // The cooldown period for regular proofs (in minutes). uint256 proofRegularCooldown; + // The cooldown period for oracle proofs (in minutes). uint256 proofOracleCooldown; + // The minimum time window allowed for a proof submission (in minutes). uint16 proofMinWindow; + // The maximum time window allowed for a proof submission (in minutes). uint16 proofMaxWindow; + // The window multiplier used to calculate proof time windows (in + // percentage). uint16 proofWindowMultiplier; - // Group 4: eth deposit related configs + // --------------------------------------------------------------------- + // Group 4: ETH deposit related configs + // --------------------------------------------------------------------- + // The size of the ETH deposit ring buffer. uint256 ethDepositRingBufferSize; + // The minimum number of ETH deposits allowed per block. uint64 ethDepositMinCountPerBlock; + // The maximum number of ETH deposits allowed per block. uint64 ethDepositMaxCountPerBlock; + // The minimum amount of ETH required for a deposit. uint96 ethDepositMinAmount; + // The maximum amount of ETH allowed for a deposit. uint96 ethDepositMaxAmount; + // The gas cost for processing an ETH deposit. uint256 ethDepositGas; + // The maximum fee allowed for an ETH deposit. uint256 ethDepositMaxFee; - // Group 5: tokenomics + // --------------------------------------------------------------------- + // Group 5: Tokenomics + // --------------------------------------------------------------------- + // The multiplier for calculating rewards for an open proposal (in + // percentage). uint8 rewardOpenMultipler; + // The maximum count of open proposals considered for rewards + // calculation. uint32 rewardOpenMaxCount; + // The maximum penalty for delaying rewards in basis points (bps). uint32 rewardMaxDelayPenalty; } - // Struct holding state variables + /// @dev Struct holding state variables. struct StateVariables { uint32 feePerGas; uint64 genesisHeight; @@ -54,8 +94,8 @@ library TaikoData { uint64 numEthDeposits; } - // Struct representing input data for block metadata - // 2 slots + /// @dev Struct representing input data for block metadata. + /// 2 slots. struct BlockMetadataInput { bytes32 txListHash; address beneficiary; @@ -64,9 +104,9 @@ library TaikoData { bool cacheTxListInfo; } - // Struct representing block metadata - // Warning: changing this struct requires changing LibUtils.hashMetadata - // accordingly. + /// @dev Struct representing block metadata. + /// Warning: changing this struct requires changing {LibUtils.hashMetadata} + /// accordingly. struct BlockMetadata { uint64 id; uint64 timestamp; @@ -82,7 +122,7 @@ library TaikoData { TaikoData.EthDeposit[] depositsProcessed; } - // Struct representing block evidence + /// @dev Struct representing block evidence. struct BlockEvidence { bytes32 metaHash; bytes32 parentHash; @@ -95,8 +135,8 @@ library TaikoData { bytes proofs; } - // Struct representing fork choice data - // 4 slots + /// @dev Struct representing fork choice data. + /// 4 slots. struct ForkChoice { // Key is only written/read for the 1st fork choice. bytes32 key; @@ -107,43 +147,43 @@ library TaikoData { uint32 gasUsed; } - // Struct representing a block - // 5 slots + /// @dev Struct representing a block. + /// 5 slots. struct Block { - // slot 1: ForkChoice storage are reusable + // Slot 1: ForkChoice storage are reusable mapping(uint256 forkChoiceId => ForkChoice) forkChoices; - // slot 2 + // Slot 2 bytes32 metaHash; - // slot 3: (13 bytes available) + // Slot 3: (13 bytes available) uint64 blockId; uint32 gasLimit; uint24 nextForkChoiceId; uint24 verifiedForkChoiceId; bool proverReleased; - // slot 4 + // Slot 4 address proposer; uint32 feePerGas; uint64 proposedAt; - // slot 5 + // Slot 5 address assignedProver; uint32 rewardPerGas; uint64 proofWindow; } - // Struct representing information about a transaction list + /// @dev Struct representing information about a transaction list. struct TxListInfo { uint64 validSince; uint24 size; } - // Struct representing an Ethereum deposit + /// @dev Struct representing an Ethereum deposit. struct EthDeposit { address recipient; uint96 amount; uint64 id; } - // Struct holding the state variables for the Taiko contract + /// @dev Struct holding the state variables for the {TaikoL1} contract. struct State { // Ring buffer for proposed blocks and a some recent verified blocks. mapping(uint256 blockId_mode_blockRingBufferSize => Block) blocks; @@ -158,7 +198,6 @@ library TaikoData { mapping(uint256 depositId_mode_ethDepositRingBufferSize => uint256) ethDeposits; mapping(address account => uint256 balance) taikoTokenBalances; - // Never or rarely changed // Slot 7: never or rarely changed uint64 genesisHeight; uint64 genesisTimestamp; diff --git a/packages/protocol/contracts/L1/TaikoErrors.sol b/packages/protocol/contracts/L1/TaikoErrors.sol index 19f2e59bc2..3e05611a60 100644 --- a/packages/protocol/contracts/L1/TaikoErrors.sol +++ b/packages/protocol/contracts/L1/TaikoErrors.sol @@ -6,15 +6,12 @@ pragma solidity ^0.8.20; -/** - * @title TaikoErrors - Custom error declarations for the Taiko protocol - * @notice This contract provides custom error declarations used in the Taiko - * protocol. - * Each error corresponds to specific situations where exceptions might - * be thrown. - */ +/// @title TaikoErrors +/// @notice This abstract contract provides custom error declartions used in +/// the Taiko protocol. Each error corresponds to specific situations where +/// exceptions might be thrown. abstract contract TaikoErrors { - // The following custom errors must match the definitions in + // NOTE: The following custom errors must match the definitions in // `L1/libs/*.sol`. error L1_ALREADY_PROVEN(); error L1_BATCH_NOT_AUCTIONABLE(); diff --git a/packages/protocol/contracts/L1/TaikoEvents.sol b/packages/protocol/contracts/L1/TaikoEvents.sol index d1e6c95d6d..8e719e7a86 100644 --- a/packages/protocol/contracts/L1/TaikoEvents.sol +++ b/packages/protocol/contracts/L1/TaikoEvents.sol @@ -8,27 +8,22 @@ pragma solidity ^0.8.20; import { TaikoData } from "./TaikoData.sol"; -/** - * @title TaikoEvents - Event declarations for the Taiko protocol - * @notice This contract provides event declarations for the Taiko protocol, - * which are emitted during block proposal, proof, verification, - * and Ethereum deposit processes. - */ +/// @title TaikoEvents +/// @notice This abstract contract provides event declarations for the Taiko +/// protocol, which are emitted during block proposal, proof, verification, and +/// Ethereum deposit processes. +/// @dev The events defined here must match the definitions in the corresponding +/// L1 libraries. abstract contract TaikoEvents { - // The following events must match the definitions in corresponding L1 - // libraries. - - /** - * @dev Emitted when a block is proposed - * @param blockId The ID of the proposed block. - * @param assignedProver The address of the assigned prover for the block. - * @param rewardPerGas The reward per gas unit for processing transactions - * in the block. - * @param feePerGas The fee per gas unit used for processing transactions in - * the block. - * @param meta The block metadata containing information about the proposed - * block. - */ + /// @dev Emitted when a block is proposed. + /// @param blockId The ID of the proposed block. + /// @param assignedProver The address of the assigned prover for the block. + /// @param rewardPerGas The reward per gas unit for processing transactions + /// in the block. + /// @param feePerGas The fee per gas unit used for processing transactions + /// in the block. + /// @param meta The block metadata containing information about the proposed + /// block. event BlockProposed( uint256 indexed blockId, address indexed assignedProver, @@ -37,15 +32,13 @@ abstract contract TaikoEvents { TaikoData.BlockMetadata meta ); - /** - * @dev Emitted when a block is proven - * @param blockId The ID of the proven block. - * @param parentHash The hash of the parent block. - * @param blockHash The hash of the proven block. - * @param signalRoot The signal root of the proven block. - * @param prover The address of the prover who submitted the proof. - * @param parentGasUsed The gas used in the parent block. - */ + /// @dev Emitted when a block is proven. + /// @param blockId The ID of the proven block. + /// @param parentHash The hash of the parent block. + /// @param blockHash The hash of the proven block. + /// @param signalRoot The signal root of the proven block. + /// @param prover The address of the prover who submitted the proof. + /// @param parentGasUsed The gas used in the parent block. event BlockProven( uint256 indexed blockId, bytes32 parentHash, @@ -55,17 +48,14 @@ abstract contract TaikoEvents { uint32 parentGasUsed ); - /** - * @dev Emitted when a block is verified - * @param blockId The ID of the verified block. - * @param blockHash The hash of the verified block. - * @param prover The address of the prover associated with the verified - * block. - * @param blockFee The fee collected from processing transactions in the - * block. - * @param proofReward The reward earned by the prover for submitting the - * proof. - */ + /// @dev Emitted when a block is verified. + /// @param blockId The ID of the verified block. + /// @param blockHash The hash of the verified block. + /// @param prover The address of the prover that proved the block which is + /// verified. + /// @param blockFee The fee paid by the proposer for proposing the block. + /// @param proofReward The reward earned by the prover for submitting the + /// proof. event BlockVerified( uint256 indexed blockId, bytes32 blockHash, @@ -74,10 +64,8 @@ abstract contract TaikoEvents { uint64 proofReward ); - /** - * @dev Emitted when an Ethereum deposit is made - * @param deposit The Ethereum deposit information including recipient, - * amount, and ID. - */ + /// @dev Emitted when an Ethereum deposit is made. + /// @param deposit The Ethereum deposit information including recipient, + /// amount, and ID. event EthDeposited(TaikoData.EthDeposit deposit); } diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index 412a39af30..f8653d8c37 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -21,12 +21,13 @@ import { TaikoErrors } from "./TaikoErrors.sol"; import { TaikoData } from "./TaikoData.sol"; import { TaikoEvents } from "./TaikoEvents.sol"; -/** - * @title TaikoL1 - * @notice This contract serves as the Layer 1 contract of the Taiko protocol, - * providing functionalities for proposing, proving, and verifying blocks. It - * also handles deposit and withdrawal of Taiko tokens and Ether. - */ +/// @title TaikoL1 +/// @notice This contract serves as the "base layer contract" of the Taiko +/// protocol, providing functionalities for proposing, proving, and verifying +/// blocks. The term "base layer contract" means that although this is usually +/// deployed on L1, it can also be deployed on L2s to create L3s ("inception +/// layers"). The contract also handles the deposit and withdrawal of Taiko +/// tokens and Ether. contract TaikoL1 is EssentialContract, ICrossChainSync, @@ -38,19 +39,16 @@ contract TaikoL1 is TaikoData.State public state; uint256[100] private __gap; - // Fallback function to receive Ether and deposit it to Layer 2. + /// @dev Fallback function to receive Ether and deposit to to Layer 2. receive() external payable { depositEtherToL2(address(0)); } - /** - * Initialize the rollup. - * - * @param _addressManager The AddressManager address. - * @param _genesisBlockHash The block hash of the genesis block. - * @param _initFeePerGas Initial (reasonable) block fee value. - * @param _initAvgProofDelay Initial (reasonable) proof window. - */ + /// @notice Initialize the rollup. + /// @param _addressManager The {AddressManager} address. + /// @param _genesisBlockHash The block hash of the genesis block. + /// @param _initFeePerGas Initial (reasonable) block fee value. + /// @param _initAvgProofDelay Initial (reasonable) proof window. function init( address _addressManager, bytes32 _genesisBlockHash, @@ -70,18 +68,14 @@ contract TaikoL1 is }); } - /** - * Propose a Taiko L2 block. - * - * @param input An abi-encoded BlockMetadataInput that the actual L2 - * block header must satisfy. - * @param txList A list of transactions in this block, encoded with RLP. - * Note, in the corresponding L2 block an _anchor transaction_ - * will be the first transaction in the block -- if there are - * `n` transactions in `txList`, then there will be up to `n + 1` - * transactions in the L2 block. - * @return meta The metadata of the proposed L2 block. - */ + /// @notice Propose a Taiko L2 block. + /// @param input An abi-encoded BlockMetadataInput that the actual L2 block + /// header must satisfy. + /// @param txList A list of transactions in this block, encoded with RLP. + /// Note, in the corresponding L2 block an "anchor transaction" will be the + /// first transaction in the block. If there are `n` transactions in the + /// `txList`, then there will be up to `n + 1` transactions in the L2 block. + /// @return meta The metadata of the proposed L2 block. function proposeBlock( bytes calldata input, bytes calldata txList @@ -108,13 +102,10 @@ contract TaikoL1 is } } - /** - * Prove a block with a zero-knowledge proof. - * - * @param blockId The index of the block to prove. This is also used - * to select the right implementation version. - * @param input An abi-encoded TaikoData.BlockEvidence object. - */ + /// @notice Prove a block with a zero-knowledge proof. + /// @param blockId The index of the block to prove. This is also used to + /// select the right implementation version. + /// @param input An abi-encoded {TaikoData.BlockEvidence} object. function proveBlock( uint256 blockId, bytes calldata input @@ -140,10 +131,8 @@ contract TaikoL1 is } } - /** - * Verify up to N blocks. - * @param maxBlocks Max number of blocks to verify. - */ + /// @notice Verify up to N blocks. + /// @param maxBlocks Max number of blocks to verify. function verifyBlocks(uint256 maxBlocks) external nonReentrant { if (maxBlocks == 0) revert L1_INVALID_PARAM(); LibVerifying.verifyBlocks({ @@ -154,11 +143,9 @@ contract TaikoL1 is }); } - /** - * Deposit Ether to Layer 2. - * @param recipient Address of the recipient for the deposited Ether on - * Layer 2. - */ + /// @notice Deposit Ether to Layer 2. + /// @param recipient Address of the recipient for the deposited Ether on + /// Layer 2. function depositEtherToL2(address recipient) public payable { LibEthDepositing.depositEtherToL2({ state: state, @@ -168,27 +155,21 @@ contract TaikoL1 is }); } - /** - * Deposit Taiko tokens to the contract. - * @param amount Amount of Taiko tokens to deposit. - */ + /// @notice Deposit Taiko tokens to the contract. + /// @param amount Amount of Taiko tokens to deposit. function depositTaikoToken(uint256 amount) public nonReentrant { LibTaikoToken.depositTaikoToken(state, AddressResolver(this), amount); } - /** - * Withdraw Taiko tokens from the contract. - * @param amount Amount of Taiko tokens to withdraw. - */ + /// @notice Withdraw Taiko tokens from the contract. + /// @param amount Amount of Taiko tokens to withdraw. function withdrawTaikoToken(uint256 amount) public nonReentrant { LibTaikoToken.withdrawTaikoToken(state, AddressResolver(this), amount); } - /** - * Check if Ether deposit is allowed for Layer 2. - * @param amount Amount of Ether to be deposited. - * @return true if Ether deposit is allowed, false otherwise. - */ + /// @notice Check if Ether deposit is allowed for Layer 2. + /// @param amount Amount of Ether to be deposited. + /// @return true if Ether deposit is allowed, false otherwise. function canDepositEthToL2(uint256 amount) public view returns (bool) { return LibEthDepositing.canDepositEthToL2({ state: state, @@ -197,11 +178,9 @@ contract TaikoL1 is }); } - /** - * Get the block fee for a given gas limit. - * @param gasLimit Gas limit for the block. - * @return The block fee in Taiko tokens. - */ + /// @notice Get the block fee for a given gas limit. + /// @param gasLimit Gas limit for the block. + /// @return The block fee in Taiko tokens. function getBlockFee(uint32 gasLimit) public view returns (uint64) { return LibUtils.getBlockFee({ state: state, @@ -210,31 +189,27 @@ contract TaikoL1 is }); } - /** - * Get the Taiko token balance for a specific address. - * @param addr Address to check the Taiko token balance. - * @return The Taiko token balance of the address. - */ + /// @notice Get the Taiko token balance for a specific address. + /// @param addr Address to check the Taiko token balance. + /// @return The Taiko token balance of the address. function getTaikoTokenBalance(address addr) public view returns (uint256) { return state.taikoTokenBalances[addr]; } - /** - * Get the details of a block. - * @param blockId Index of the block. - * @return _metaHash Metadata hash of the block. - * @return _gasLimit Gas limit of the block. - * @return _nextForkChoiceId Next fork choice ID of the block. - * @return _verifiedForkChoiceId Verified fork choice ID of the block. - * @return _proverReleased True if the prover has been released for the - * block, false otherwise. - * @return _proposer Address of the block proposer. - * @return _feePerGas Fee per gas of the block. - * @return _proposedAt Timestamp when the block was proposed. - * @return _assignedProver Address of the assigned prover for the block. - * @return _rewardPerGas Reward per gas of the block. - * @return _proofWindow Proof window of the block. - */ + /// @notice Get the details of a block. + /// @param blockId Index of the block. + /// @return _metaHash Metadata hash of the block. + /// @return _gasLimit Gas limit of the block. + /// @return _nextForkChoiceId Next fork choice ID of the block. + /// @return _verifiedForkChoiceId Verified fork choice ID of the block. + /// @return _proverReleased True if the prover has been released for the + /// block, false otherwise. + /// @return _proposer Address of the block proposer. + /// @return _feePerGas Fee per gas of the block. + /// @return _proposedAt Timestamp when the block was proposed. + /// @return _assignedProver Address of the assigned prover for the block. + /// @return _rewardPerGas Reward per gas of the block. + /// @return _proofWindow Proof window of the block. function getBlock(uint256 blockId) public view @@ -270,13 +245,11 @@ contract TaikoL1 is _proofWindow = blk.proofWindow; } - /** - * Get the fork choice for a specific block. - * @param blockId Index of the block. - * @param parentHash Parent hash of the block. - * @param parentGasUsed Gas used by the parent block. - * @return ForkChoice struct of the block. - */ + /// @notice Get the fork choice for a specific block. + /// @param blockId Index of the block. + /// @param parentHash Parent hash of the block. + /// @param parentGasUsed Gas used by the parent block. + /// @return ForkChoice data of the block. function getForkChoice( uint256 blockId, bytes32 parentHash, @@ -295,11 +268,9 @@ contract TaikoL1 is }); } - /** - * Get the block hash of the specified Layer 2 block. - * @param blockId Index of the block. - * @return Block hash of the specified block. - */ + /// @notice Get the block hash of the specified Layer 2 block. + /// @param blockId Index of the block. + /// @return Block hash of the specified block. function getCrossChainBlockHash(uint256 blockId) public view @@ -316,11 +287,9 @@ contract TaikoL1 is : bytes32(0); } - /** - * Get the signal root of the specified Layer 2 block. - * @param blockId Index of the block. - * @return Signal root of the specified block. - */ + /// @notice Get the signal root of the specified Layer 2 block. + /// @param blockId Index of the block. + /// @return Signal root of the specified block. function getCrossChainSignalRoot(uint256 blockId) public view @@ -338,10 +307,8 @@ contract TaikoL1 is : bytes32(0); } - /** - * Get the state variables of the Taiko L1 contract. - * @return StateVariables struct containing state variables. - */ + /// @notice Get the state variables of the TaikoL1 contract. + /// @return StateVariables struct containing state variables. function getStateVariables() public view @@ -350,10 +317,8 @@ contract TaikoL1 is return state.getStateVariables(); } - /** - * Get the configuration of the Taiko L1 contract. - * @return TaikoData.Config struct containing configuration parameters. - */ + /// @notice Get the configuration of the TaikoL1 contract. + /// @return Config struct containing configuration parameters. function getConfig() public pure @@ -363,18 +328,14 @@ contract TaikoL1 is return TaikoConfig.getConfig(); } - /** - * Get the name of the verifier by ID. - * @param id ID of the verifier. - * @return Verifier name. - */ + /// @notice Get the name of the proof verifier by ID. + /// @param id ID of the verifier. + /// @return Verifier name. function getVerifierName(uint16 id) public pure returns (bytes32) { return LibUtils.getVerifierName(id); } } -/** - * @title ProxiedTaikoL1 - * @dev Proxied version of the TaikoL1 contract. - */ +/// @title TaikoL1 +/// @notice Proxied version of the TaikoL1 contract. contract ProxiedTaikoL1 is Proxied, TaikoL1 { } diff --git a/packages/protocol/contracts/L1/TaikoToken.sol b/packages/protocol/contracts/L1/TaikoToken.sol index 2ba01d4ad3..104cc67e2c 100644 --- a/packages/protocol/contracts/L1/TaikoToken.sol +++ b/packages/protocol/contracts/L1/TaikoToken.sol @@ -28,17 +28,10 @@ library LibTaikoTokenConfig { uint8 public constant DECIMALS = uint8(8); } -/** - * @title TaikoToken - * @dev TaikoToken is a ERC20 compliant token contract that extends several - * OpenZeppelin ERC20 extensions and implements additional functionalities - * specific to the Taiko protocol. - * - * It allows users to initialize, mint, burn, pause, and unpause tokens. The - * contract supports snapshots, voting, and permits for ERC20 transfers. The - * contract is also upgradable and mints initial tokens to specified recipients - * during initialization. - */ +/// @title TaikoToken +/// @notice The TaikoToken (TKO) is used for proposing blocks and also for +/// staking in the Taiko protocol. It is an ERC20 token with 8 decimal places of +/// precision. contract TaikoToken is EssentialContract, ERC20Upgradeable, @@ -57,18 +50,15 @@ contract TaikoToken is USER-FACING FUNCTIONS //////////////////////////////////////////////////////////////*/ - /** - * @notice Initializes the TaikoToken contract and mints initial tokens to - * specified recipients. - * @param _addressManager Address of the contract that manages proxy - * addresses. - * @param _name The name of the token. - * @param _symbol The symbol of the token. - * @param _premintRecipients An array of addresses to receive initial token - * minting. - * @param _premintAmounts An array of token amounts to mint for each - * corresponding recipient. - */ + /// @notice Initializes the TaikoToken contract and mints initial tokens to + /// specified recipients. + /// @param _addressManager The {AddressManager} address. + /// @param _name The name of the token. + /// @param _symbol The symbol of the token. + /// @param _premintRecipients An array of addresses to receive initial token + /// minting. + /// @param _premintAmounts An array of token amounts to mint for each + /// corresponding recipient. function init( address _addressManager, string calldata _name, @@ -92,35 +82,24 @@ contract TaikoToken is } } - /** - * @notice Creates a new token snapshot. - * @dev Only the contract owner can call this function. - */ + /// @notice Creates a new token snapshot. function snapshot() public onlyOwner { _snapshot(); } - /** - * @notice Pauses all token transfers. - * @dev Only the contract owner can call this function. - */ + /// @notice Pauses token transfers. function pause() public onlyOwner { _pause(); } - /** - * @notice Unpauses token transfers. - * @dev Only the contract owner can call this function. - */ + /// @notice Unpauses token transfers. function unpause() public onlyOwner { _unpause(); } - /** - * @notice Mints new tokens to the specified address. - * @param to The address to receive the minted tokens. - * @param amount The amount of tokens to mint. - */ + /// @notice Mints new tokens to the specified address. + /// @param to The address to receive the minted tokens. + /// @param amount The amount of tokens to mint. function mint( address to, uint256 amount @@ -131,11 +110,9 @@ contract TaikoToken is _mint(to, amount); } - /** - * @notice Burns tokens from the specified address. - * @param from The address to burn tokens from. - * @param amount The amount of tokens to burn. - */ + /// @notice Burns tokens from the specified address. + /// @param from The address to burn tokens from. + /// @param amount The amount of tokens to burn. function burn( address from, uint256 amount @@ -146,12 +123,10 @@ contract TaikoToken is _burn(from, amount); } - /** - * @notice Transfers tokens to a specified address. - * @param to The address to transfer tokens to. - * @param amount The amount of tokens to transfer. - * @return A boolean indicating whether the transfer was successful or not. - */ + /// @notice Transfers tokens to a specified address. + /// @param to The address to transfer tokens to. + /// @param amount The amount of tokens to transfer. + /// @return A boolean indicating whether the transfer was successful or not. function transfer( address to, uint256 amount @@ -164,13 +139,11 @@ contract TaikoToken is return ERC20Upgradeable.transfer(to, amount); } - /** - * @notice Transfers tokens from one address to another. - * @param from The address to transfer tokens from. - * @param to The address to transfer tokens to. - * @param amount The amount of tokens to transfer. - * @return A boolean indicating whether the transfer was successful or not. - */ + /// @notice Transfers tokens from one address to another. + /// @param from The address to transfer tokens from. + /// @param to The address to transfer tokens to. + /// @param amount The amount of tokens to transfer. + /// @return A boolean indicating whether the transfer was successful or not. function transferFrom( address from, address to, @@ -184,10 +157,8 @@ contract TaikoToken is return ERC20Upgradeable.transferFrom(from, to, amount); } - /** - * @notice Returns the number of decimals used for token display. - * @return The number of decimals used for token display. - */ + /// @notice Returns the number of decimals used for token display. + /// @return The number of decimals used for token display. function decimals() public pure override returns (uint8) { return LibTaikoTokenConfig.DECIMALS; } @@ -208,7 +179,6 @@ contract TaikoToken is super._beforeTokenTransfer(from, to, amount); } - // The following functions are overrides required by Solidity. function _afterTokenTransfer( address from, address to, @@ -245,8 +215,6 @@ contract TaikoToken is } } -/** - * @title ProxiedTaikoToken - * @dev Proxied version of the TaikoToken contract. - */ +/// @title ProxiedTaikoToken +/// @notice Proxied version of the TaikoToken contract. contract ProxiedTaikoToken is Proxied, TaikoToken { } diff --git a/packages/protocol/contracts/L1/libs/LibEthDepositing.sol b/packages/protocol/contracts/L1/libs/LibEthDepositing.sol index 863605de09..9dc0d7d556 100644 --- a/packages/protocol/contracts/L1/libs/LibEthDepositing.sol +++ b/packages/protocol/contracts/L1/libs/LibEthDepositing.sol @@ -11,10 +11,8 @@ import { LibMath } from "../../libs/LibMath.sol"; import { AddressResolver } from "../../common/AddressResolver.sol"; import { TaikoData } from "../TaikoData.sol"; -/** - * @title LibEthDepositing Library - * @notice A library for handling Ethereum deposits in the Taiko system. - */ +/// @title LibEthDepositing +/// @notice A library for handling Ethereum deposits in the Taiko protocol. library LibEthDepositing { using LibAddress for address; using LibMath for uint256; @@ -23,13 +21,11 @@ library LibEthDepositing { error L1_INVALID_ETH_DEPOSIT(); - /** - * @notice Deposit Ethereum to Layer 2. - * @param state The current state of the Taiko system. - * @param config Configuration for deposits. - * @param resolver The AddressResolver instance for address resolution. - * @param recipient The address of the deposit recipient. - */ + /// @dev Deposits Ether into Taiko. + /// @param state The current state of the Taiko protocol. + /// @param config The config of the Taiko protocol. + /// @param resolver The {AddressResolver} instance for address resolution. + /// @param recipient The address of the deposit recipient. function depositEtherToL2( TaikoData.State storage state, TaikoData.Config memory config, @@ -66,13 +62,11 @@ library LibEthDepositing { } } - /** - * @notice Process the ETH deposits in a batched manner. - * @param state The current state of the Taiko system. - * @param config Configuration for deposits. - * @param feeRecipient Address to receive the deposit fee. - * @return deposits The array of processed deposits. - */ + /// @dev Processes the ETH deposits in a batched manner. + /// @param state The current state of the Taiko protocol. + /// @param config The config of the Taiko protocol. + /// @param feeRecipient Address to receive the deposit fee. + /// @return deposits The array of processed deposits. function processDeposits( TaikoData.State storage state, TaikoData.Config memory config, @@ -103,7 +97,7 @@ library LibEthDepositing { state.ethDeposits[j % config.ethDepositRingBufferSize]; deposits[i] = TaikoData.EthDeposit({ recipient: address(uint160(data >> 96)), - amount: uint96(data), // works + amount: uint96(data), id: j }); uint96 _fee = @@ -126,13 +120,11 @@ library LibEthDepositing { } } - /** - * @notice Check if the given deposit amount is valid. - * @param state The current state of the Taiko system. - * @param config Configuration for deposits. - * @param amount The amount to deposit. - * @return true if the deposit is valid, false otherwise. - */ + /// @dev Checks if the given deposit amount is valid. + /// @param state The current state of the Taiko protocol. + /// @param config The config of the Taiko protocol. + /// @param amount The amount to deposit. + /// @return true if the deposit is valid, false otherwise. function canDepositEthToL2( TaikoData.State storage state, TaikoData.Config memory config, @@ -150,11 +142,9 @@ library LibEthDepositing { } } - /** - * @notice Compute the hash for a set of deposits. - * @param deposits Array of EthDeposit to hash. - * @return The computed hash. - */ + /// @dev Computes the hash of the given deposits. + /// @param deposits The deposits to hash. + /// @return The computed hash. function hashEthDeposits(TaikoData.EthDeposit[] memory deposits) internal pure @@ -163,6 +153,10 @@ library LibEthDepositing { return keccak256(abi.encode(deposits)); } + /// @dev Encodes the given deposit into a uint256. + /// @param addr The address of the deposit recipient. + /// @param amount The amount of the deposit. + /// @return The encoded deposit. function _encodeEthDeposit( address addr, uint256 amount diff --git a/packages/protocol/contracts/L1/libs/verifiers/LibZKPVerifier.sol b/packages/protocol/contracts/L1/libs/verifiers/LibZKPVerifier.sol index cf246e38dd..3df7010ee3 100644 --- a/packages/protocol/contracts/L1/libs/verifiers/LibZKPVerifier.sol +++ b/packages/protocol/contracts/L1/libs/verifiers/LibZKPVerifier.sol @@ -6,27 +6,21 @@ pragma solidity ^0.8.20; -// Taiko System Dependencies import { AddressResolver } from "../../../common/AddressResolver.sol"; import { LibUtils } from "../LibUtils.sol"; import { TaikoData } from "../../TaikoData.sol"; -/** - * @title LibZKPVerifier Library - * @notice A library for verifying Zero-Knowledge Proofs (ZKP) in the Taiko - * system. - */ +/// @title LibZKPVerifier +/// @notice A library for verifying ZK proofs in the Taiko protocol. library LibZKPVerifier { // Custom error to signal an invalid proof. error L1_INVALID_PROOF(); - /** - * @notice Verifies the provided proof using the designated verifier. - * @param resolver The AddressResolver instance to resolve the verifier's - * address. - * @param proof The ZKP to verify. - * @param verifierId The identifier of the ZKP verifier. - */ + /// @dev Verifies the provided proof using the designated verifier. + /// @param resolver The {AddressResolver} instance to resolve the verifier's + /// address. + /// @param proof The ZKP to verify. + /// @param verifierId The identifier of the ZKP verifier. function verifyProof( AddressResolver resolver, bytes memory proof, diff --git a/packages/protocol/contracts/L2/LibL2Consts.sol b/packages/protocol/contracts/L2/LibL2Consts.sol index b9e47948ce..311cf13923 100644 --- a/packages/protocol/contracts/L2/LibL2Consts.sol +++ b/packages/protocol/contracts/L2/LibL2Consts.sol @@ -6,11 +6,9 @@ pragma solidity ^0.8.20; -/** - * @title LibL2Consts Library - * @notice This library contains constants related to Layer 2 operations. - */ +/// @title LibL2Consts +/// @notice This library contains constants related to Layer 2 operations. library LibL2Consts { - /// @notice Gas cost associated with the anchor transaction. + // Gas cost associated with the anchor transaction. uint32 public constant ANCHOR_GAS_COST = 180_000; // owner: david } diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index adf12964df..879a238f32 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -16,22 +16,14 @@ import { TaikoL2Signer } from "./TaikoL2Signer.sol"; import { SafeCastUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; -/** - * @title TaikoL2 - * @dev TaikoL2 is a smart contract that handles cross-layer message - * verification and manages EIP-1559 gas pricing for Layer 2 (L2) operations. - * - * It is used to anchor the latest L1 block details to L2 for cross-layer - * communication, manage EIP-1559 parameters for gas pricing, and store verified - * L1 block information. - * - * TaikoL2 also implements a signing mechanism for L2 messages and inherits - * essential functionalities from `EssentialContract`, `TaikoL2Signer`, and - * `ICrossChainSync` interfaces. - * - * This contract is upgradeable and can be used in combination with - * `ProxiedTaikoL2`. - */ +/// @title TaikoL2 +/// @notice Taiko L2 is a smart contract that handles cross-layer message +/// verification and manages EIP-1559 gas pricing for Layer 2 (L2) operations. +/// +/// It is used to anchor the latest L1 block details to L2 for cross-layer +/// communication, manage EIP-1559 parameters for gas pricing, and store +/// verified +/// L1 block information. contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { using SafeCastUpgradeable for uint256; using LibMath for uint256; @@ -111,12 +103,9 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { USER-FACING FUNCTIONS //////////////////////////////////////////////////////////////*/ - /** - * @notice Initializes the TaikoL2 contract. - * @param _addressManager Address of the contract that manages proxy - * addresses. - * @param _param1559 EIP-1559 parameters to set up the gas pricing model. - */ + /// @notice Initializes the TaikoL2 contract. + /// @param _addressManager Address of the {AddressManager} contract. + /// @param _param1559 EIP-1559 parameters to set up the gas pricing model. function init( address _addressManager, EIP1559Params calldata _param1559 @@ -131,13 +120,8 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { if (_param1559.gasIssuedPerSecond != 0) { if ( - _param1559.basefee == 0 - // - || _param1559.gasExcessMax == 0 - // - || _param1559.gasTarget == 0 - // - || _param1559.ratio2x1x == 0 + _param1559.basefee == 0 || _param1559.gasExcessMax == 0 + || _param1559.gasTarget == 0 || _param1559.ratio2x1x == 0 ) revert L2_INVALID_1559_PARAMS(); (uint128 xscale, uint128 yscale) = Lib1559Math.calculateScales({ @@ -168,15 +152,14 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { } } - /** - * @notice Anchors the latest L1 block details to L2 for cross-layer message - * verification. - * @param l1Hash The latest L1 block hash when this block was proposed. - * @param l1SignalRoot The latest value of the L1 "signal service storage - * root". - * @param l1Height The latest L1 block height when this block was proposed. - * @param parentGasUsed The gas used in the parent block. - */ + /// @notice Anchors the latest L1 block details to L2 for cross-layer + /// message + /// verification. + /// @param l1Hash The latest L1 block hash when this block was proposed. + /// @param l1SignalRoot The latest value of the L1 signal service storage + /// root. + /// @param l1Height The latest L1 block height when this block was proposed. + /// @param parentGasUsed The gas used in the parent block. function anchor( bytes32 l1Hash, bytes32 l1SignalRoot, @@ -196,7 +179,7 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { revert L2_PUBLIC_INPUT_HASH_MISMATCH(publicInputHash, prevPIH); } - // replace the oldest block hash with the parent's blockhash + // Replace the oldest block hash with the parent's blockhash publicInputHash = currPIH; _l2Hashes[parentHeight] = parentHash; @@ -241,13 +224,11 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { }); } - /** - * @notice Gets the basefee and gas excess using EIP-1559 configuration for - * given parameters. - * @param timeSinceParent Time elapsed since the parent block's timestamp. - * @param parentGasUsed Gas used in the parent block. - * @return _basefee The calculated EIP-1559 basefee. - */ + /// @notice Gets the basefee and gas excess using EIP-1559 configuration for + /// the given parameters. + /// @param timeSinceParent Time elapsed since the parent block's timestamp. + /// @param parentGasUsed Gas used in the parent block. + /// @return _basefee The calculated EIP-1559 basefee. function getBasefee( uint64 timeSinceParent, uint32 parentGasUsed @@ -263,14 +244,14 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { }); } - /** - * @notice Retrieves the L1 block hash for the given L1 block number or the - * latest synced L1 block hash if the number is zero. - * @param number The L1 block number to retrieve the block hash for, or zero - * to fetch the latest synced L1 block hash. - * @return The L1 block hash for the specified L1 block number or the latest - * synced L1 block hash. - */ + /// @notice Retrieves the L1 block hash for the given L1 block number or the + /// latest synced L1 block hash if the number is zero. + /// @param number The L1 block number to retrieve the block hash for, or + /// zero + /// to fetch the latest synced L1 block hash. + /// @return The L1 block hash for the specified L1 block number or the + /// latest + /// synced L1 block hash. function getCrossChainBlockHash(uint256 number) public view @@ -281,14 +262,12 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { return _l1VerifiedBlocks[_number].blockHash; } - /** - * @notice Retrieves the signal root for the given L1 block number or the - * latest synced L1 signal root if the number is zero. - * @param number The L1 block number to retrieve the signal root for, or - * zero to fetch the latest synced L1 signal root. - * @return The signal root for the specified L1 block number or the latest - * synced L1 signal root. - */ + /// @notice Retrieves the signal root for the given L1 block number or the + /// latest synced L1 signal root if the number is zero. + /// @param number The L1 block number to retrieve the signal root for, or + /// zero to fetch the latest synced L1 signal root. + /// @return The signal root for the specified L1 block number or the latest + /// synced L1 signal root. function getCrossChainSignalRoot(uint256 number) public view @@ -299,12 +278,10 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { return _l1VerifiedBlocks[_number].signalRoot; } - /** - * @notice Retrieves the block hash for the given L2 block number. - * @param number The L2 block number to retrieve the block hash for. - * @return The block hash for the specified L2 block number, or zero if the - * block number is greater than or equal to the current block number. - */ + /// @notice Retrieves the block hash for the given L2 block number. + /// @param number The L2 block number to retrieve the block hash for. + /// @return The block hash for the specified L2 block number, or zero if the + /// block number is greater than or equal to the current block number. function getBlockHash(uint256 number) public view returns (bytes32) { if (number >= block.number) { return 0; @@ -315,11 +292,10 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { } } - /** - * @notice Retrieves the current EIP-1559 configuration details. - * @return The current EIP-1559 configuration details, including the yscale, - * xscale, and gasIssuedPerSecond parameters. - */ + /// @notice Retrieves the current EIP-1559 configuration details. + /// @return The current EIP-1559 configuration details, including the + /// yscale, + /// xscale, and gasIssuedPerSecond parameters. function getEIP1559Config() public view @@ -340,7 +316,7 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { { bytes32[256] memory inputs; unchecked { - // put the previous 255 blockhashes (excluding the parent's) into a + // Put the previous 255 blockhashes (excluding the parent's) into a // ring buffer. for (uint256 i; i < 255 && blockNumber >= i + 1; ++i) { uint256 j = blockNumber - i - 1; @@ -389,15 +365,13 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync { }); if (_basefee == 0) { - // To make sure when 1559 is enabled, the basefee is non-zero - // (geth never use 0 values for basefee) + // To make sure when EIP-1559 is enabled, the basefee is non-zero + // (Geth never uses 0 values for basefee) _basefee = 1; } } } -/** - * @title ProxiedTaikoL2 - * @dev Proxied version of the TaikoL2 contract. - */ +/// @title ProxiedTaikoL2 +/// @notice Proxied version of the TaikoL2 contract. contract ProxiedTaikoL2 is Proxied, TaikoL2 { } diff --git a/packages/protocol/contracts/L2/TaikoL2Signer.sol b/packages/protocol/contracts/L2/TaikoL2Signer.sol index 42b1c673e7..82fbeffcd5 100644 --- a/packages/protocol/contracts/L2/TaikoL2Signer.sol +++ b/packages/protocol/contracts/L2/TaikoL2Signer.sol @@ -8,14 +8,11 @@ pragma solidity ^0.8.20; import { LibUint512Math } from "../libs/LibUint512Math.sol"; -/** - * @title TaikoL2Signer - * @notice This contract allows for signing operations related to Layer 2 (L2) - * within the Taiko ecosystem. - * It uses precomputed values for optimized signature creation. - */ +/// @title TaikoL2Signer +/// @notice This contract allows for signing operations required on Taiko L2. +/// @dev It uses precomputed values for optimized signature creation. abstract contract TaikoL2Signer { - // Constants related to the golden touch mechanism. + // Constants related to the golden touch signature. address public constant GOLDEN_TOUCH_ADDRESS = 0x0000777735367b36bC9B61C50022d9D0700dB4Ec; uint256 public constant GOLDEN_TOUCH_PRIVATEKEY = @@ -51,14 +48,12 @@ abstract contract TaikoL2Signer { error L2_INVALID_GOLDEN_TOUCH_K(); - /** - * @notice Signs the provided digest using the golden touch mechanism. - * @param digest The hash of the data to be signed. - * @param k The selector for signature optimization. - * @return v The recovery id. - * @return r The r component of the signature. - * @return s The s component of the signature. - */ + /// @notice Signs the provided digest using the golden touch mechanism. + /// @param digest The hash of the data to be signed. + /// @param k The selector for signature optimization. + /// @return v The recovery id. + /// @return r The r component of the signature. + /// @return s The s component of the signature. function signAnchor( bytes32 digest, uint8 k @@ -95,14 +90,12 @@ abstract contract TaikoL2Signer { } } - /** - * @dev Computes base^e mod m. - * @param baseLow Lower 256 bits of the base. - * @param baseHigh Higher 256 bits of the base. - * @param e Exponent. - * @param m Modulus. - * @return o Result. - */ + /// @dev Computes base^e mod m. + /// @param baseLow Lower 256 bits of the base. + /// @param baseHigh Higher 256 bits of the base. + /// @param e Exponent. + /// @param m Modulus. + /// @return o Result. function _expmod( uint256 baseLow, uint256 baseHigh, @@ -116,7 +109,7 @@ abstract contract TaikoL2Signer { assembly { // Define pointer let p := mload(0x40) - // store data assembly-favouring ways + // Store data in assembly-favouring ways mstore(p, 0x40) // Length of Base mstore(add(p, 0x20), 0x20) // Length of Exponent mstore(add(p, 0x40), 0x20) // Length of Modulus diff --git a/packages/protocol/contracts/bridge/Bridge.sol b/packages/protocol/contracts/bridge/Bridge.sol index 0fe91385b4..9f4da7533c 100644 --- a/packages/protocol/contracts/bridge/Bridge.sol +++ b/packages/protocol/contracts/bridge/Bridge.sol @@ -18,12 +18,9 @@ import { LibBridgeRetry } from "./libs/LibBridgeRetry.sol"; import { LibBridgeSend } from "./libs/LibBridgeSend.sol"; import { LibBridgeStatus } from "./libs/LibBridgeStatus.sol"; -/** - * This contract is a Bridge contract which is deployed on both L1 and L2. Mostly - * a thin wrapper - * which calls the library implementations. See _IBridge_ for more details. - * @dev The code hash for the same address on L1 and L2 may be different. - */ +/// @title Bridge +/// @notice See the documentation for {IBridge}. +/// @dev The code hash for the same address on L1 and L2 may be different. contract Bridge is EssentialContract, IBridge, BridgeErrors { using LibBridgeData for Message; @@ -39,23 +36,16 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { receive() external payable { } - /** - * Initializer to be called after being deployed behind a proxy. - * @dev Initializer function to setup the EssentialContract. - * @param _addressManager The address of the AddressManager contract. - */ + /// @notice Initializes the contract. + /// @param _addressManager The address of the {AddressManager} contract. function init(address _addressManager) external initializer { EssentialContract._init(_addressManager); } - /** - * Sends a message from the current chain to the destination chain specified - * in the message. - * @dev Sends a message by calling the LibBridgeSend.sendMessage library - * function. - * @param message The message to send. (See IBridge) - * @return msgHash The hash of the message that was sent. - */ + /// @notice Sends a message from the current chain to the destination chain + /// specified in the message. + /// @param message The message to send. (See {IBridge}) + /// @return msgHash The hash of the message that was sent. function sendMessage(Message calldata message) external payable @@ -69,15 +59,11 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { }); } - /** - * Releases the Ether locked in the bridge as part of a cross-chain - * transfer. - * @dev Releases the Ether by calling the LibBridgeRelease.releaseEther - * library function. - * @param message The message containing the details of the Ether transfer. - * (See IBridge) - * @param proof The proof of the cross-chain transfer. - */ + /// @notice Releases the Ether locked in the bridge as part of a cross-chain + /// transfer. + /// @param message The message containing the details of the Ether transfer. + /// (See {IBridge}) + /// @param proof The proof of the cross-chain transfer. function releaseEther( IBridge.Message calldata message, bytes calldata proof @@ -93,13 +79,9 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { }); } - /** - * Processes a message received from another chain. - * @dev Processes the message by calling the LibBridgeProcess.processMessage - * library function. - * @param message The message to process. - * @param proof The proof of the cross-chain transfer. - */ + /// @notice Processes a message received from another chain. + /// @param message The message to process. + /// @param proof The proof of the cross-chain transfer. function processMessage( Message calldata message, bytes calldata proof @@ -115,14 +97,10 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { }); } - /** - * Retries sending a message that previously failed to send. - * @dev Retries the message by calling the LibBridgeRetry.retryMessage - * library function. - * @param message The message to retry. - * @param isLastAttempt Specifies whether this is the last attempt to send - * the message. - */ + /// @notice Retries sending a message that previously failed to send. + /// @param message The message to retry. + /// @param isLastAttempt Specifies whether this is the last attempt to send + /// the message. function retryMessage( Message calldata message, bool isLastAttempt @@ -138,11 +116,9 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { }); } - /** - * Check if the message with the given hash has been sent. - * @param msgHash The hash of the message. - * @return Returns true if the message has been sent, false otherwise. - */ + /// @notice Check if the message with the given hash has been sent. + /// @param msgHash The hash of the message. + /// @return Returns true if the message has been sent, false otherwise. function isMessageSent(bytes32 msgHash) public view @@ -152,13 +128,11 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { return LibBridgeSend.isMessageSent(AddressResolver(this), msgHash); } - /** - * Check if the message with the given hash has been received. - * @param msgHash The hash of the message. - * @param srcChainId The source chain ID. - * @param proof The proof of message receipt. - * @return Returns true if the message has been received, false otherwise. - */ + /// @notice Check if the message with the given hash has been received. + /// @param msgHash The hash of the message. + /// @param srcChainId The source chain ID. + /// @param proof The proof of message receipt. + /// @return Returns true if the message has been received, false otherwise. function isMessageReceived( bytes32 msgHash, uint256 srcChainId, @@ -178,13 +152,11 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { }); } - /** - * Check if the message with the given hash has failed. - * @param msgHash The hash of the message. - * @param destChainId The destination chain ID. - * @param proof The proof of message failure. - * @return Returns true if the message has failed, false otherwise. - */ + /// @notice Check if the message with the given hash has failed. + /// @param msgHash The hash of the message. + /// @param destChainId The destination chain ID. + /// @param proof The proof of message failure. + /// @return Returns true if the message has failed, false otherwise. function isMessageFailed( bytes32 msgHash, uint256 destChainId, @@ -204,11 +176,9 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { }); } - /** - * Get the status of the message with the given hash. - * @param msgHash The hash of the message. - * @return Returns the status of the message. - */ + /// @notice Get the status of the message with the given hash. + /// @param msgHash The hash of the message. + /// @return Returns the status of the message. function getMessageStatus(bytes32 msgHash) public view @@ -218,31 +188,24 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { return LibBridgeStatus.getMessageStatus(msgHash); } - /** - * Get the current context - * @return Returns the current context. - */ + /// @notice Get the current context. + /// @return Returns the current context. function context() public view returns (Context memory) { return _state.ctx; } - /** - * Check if the Ether associated with the given message hash has been - * released. - * @param msgHash The hash of the message. - * @return Returns true if the Ether has been released, false otherwise. - */ + /// @notice Check if the Ether associated with the given message hash has + /// been released. + /// @param msgHash The hash of the message. + /// @return Returns true if the Ether has been released, false otherwise. function isEtherReleased(bytes32 msgHash) public view returns (bool) { return _state.etherReleased[msgHash]; } - /** - * Check if the destination chain with the given ID is enabled. - * @param _chainId The ID of the chain. - * @return enabled Returns true if the destination chain is enabled, false - * otherwise. - */ - + /// @notice Check if the destination chain with the given ID is enabled. + /// @param _chainId The ID of the chain. + /// @return enabled Returns true if the destination chain is enabled, false + /// otherwise. function isDestChainEnabled(uint256 _chainId) public view @@ -252,11 +215,9 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { LibBridgeSend.isDestChainEnabled(AddressResolver(this), _chainId); } - /** - * Compute the hash of a given message. - * @param message The message to compute the hash for. - * @return Returns the hash of the message. - */ + /// @notice Compute the hash of a given message. + /// @param message The message to compute the hash for. + /// @return Returns the hash of the message. function hashMessage(Message calldata message) public pure @@ -266,11 +227,9 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { return LibBridgeData.hashMessage(message); } - /** - * Get the slot associated with a given message hash status. - * @param msgHash The hash of the message. - * @return Returns the slot associated with the given message hash status. - */ + /// @notice Get the slot associated with a given message hash status. + /// @param msgHash The hash of the message. + /// @return Returns the slot associated with the given message hash status. function getMessageStatusSlot(bytes32 msgHash) public pure @@ -280,8 +239,6 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors { } } -/** - * @title ProxiedBridge - * @dev Proxied version of the Bridge contract. - */ +/// @title ProxiedBridge +/// @notice Proxied version of the Bridge contract. contract ProxiedBridge is Proxied, Bridge { } diff --git a/packages/protocol/contracts/bridge/EtherVault.sol b/packages/protocol/contracts/bridge/EtherVault.sol index 485efab1a6..57bc107c5e 100644 --- a/packages/protocol/contracts/bridge/EtherVault.sol +++ b/packages/protocol/contracts/bridge/EtherVault.sol @@ -15,11 +15,10 @@ import { Proxied } from "../common/Proxied.sol"; import { LibAddress } from "../libs/LibAddress.sol"; import { BridgeErrors } from "./BridgeErrors.sol"; -/** - * This contract is initialized with 2^128 Ether and allows authorized addresses - * to release Ether. - * @dev Only the contract owner can authorize or deauthorize addresses. - */ +/// @title EtherVault +/// @notice This contract is initialized with 2^128 Ether and allows authorized +/// addresses to release Ether. +/// @dev Only the contract owner can authorize or deauthorize addresses. contract EtherVault is EssentialContract, BridgeErrors { using LibAddress for address; @@ -36,10 +35,8 @@ contract EtherVault is EssentialContract, BridgeErrors { _; } - /** - * Function to receive Ether - * @dev Only authorized addresses can send Ether to the contract - */ + /// @notice Function to receive Ether. + /// @dev Only authorized addresses can send Ether to the contract. receive() external payable { // EthVault's balance must == 0 OR the sender isAuthorized. if (address(this).balance != 0 && !isAuthorized(msg.sender)) { @@ -47,30 +44,24 @@ contract EtherVault is EssentialContract, BridgeErrors { } } - /** - * Initialize the contract with an address manager - * @param addressManager The address of the address manager - */ + /// @notice Initializes the contract with an {AddressManager}. + /// @param addressManager The address of the {AddressManager} contract. function init(address addressManager) external initializer { EssentialContract._init(addressManager); } - /** - * Transfer Ether from EtherVault to the sender, checking that the sender - * is authorized. - * @param amount Amount of Ether to send. - */ + /// @notice Transfer Ether from EtherVault to the sender, checking that the + /// sender is authorized. + /// @param amount Amount of Ether to send. function releaseEther(uint256 amount) public onlyAuthorized nonReentrant { msg.sender.sendEther(amount); emit EtherReleased(msg.sender, amount); } - /** - * Transfer Ether from EtherVault to a designated address, checking that the - * sender is authorized. - * @param recipient Address to receive Ether. - * @param amount Amount of ether to send. - */ + /// @notice Transfer Ether from EtherVault to a designated address, checking + /// that the sender is authorized. + /// @param recipient Address to receive Ether. + /// @param amount Amount of ether to send. function releaseEther( address recipient, uint256 amount @@ -86,11 +77,10 @@ contract EtherVault is EssentialContract, BridgeErrors { emit EtherReleased(recipient, amount); } - /** - * Set the authorized status of an address, only the owner can call this. - * @param addr Address to set the authorized status of. - * @param authorized Authorized status to set. - */ + /// @notice Set the authorized status of an address, only the owner can call + /// this. + /// @param addr Address to set the authorized status of. + /// @param authorized Authorized status to set. function authorize(address addr, bool authorized) public onlyOwner { if (addr == address(0) || _authorizedAddrs[addr] == authorized) { revert B_EV_PARAM(); @@ -99,17 +89,13 @@ contract EtherVault is EssentialContract, BridgeErrors { emit Authorized(addr, authorized); } - /** - * Get the authorized status of an address. - * @param addr Address to get the authorized status of. - */ + /// @notice Get the authorized status of an address. + /// @param addr Address to get the authorized status of. function isAuthorized(address addr) public view returns (bool) { return _authorizedAddrs[addr]; } } -/** - * @title ProxiedEtherVault - * @dev Proxied version of the EtherVault contract. - */ +/// @title ProxiedEtherVault +/// @notice Proxied version of the EtherVault contract. contract ProxiedEtherVault is Proxied, EtherVault { } diff --git a/packages/protocol/contracts/bridge/IBridge.sol b/packages/protocol/contracts/bridge/IBridge.sol index 97eab2b1af..deeb755b5d 100644 --- a/packages/protocol/contracts/bridge/IBridge.sol +++ b/packages/protocol/contracts/bridge/IBridge.sol @@ -6,11 +6,10 @@ pragma solidity ^0.8.20; -/** - * Bridge interface. - * @dev Ether is held by Bridges on L1 and by the EtherVault on L2, - * not by token vaults. - */ +/// @title IBridge +/// @notice The bridge used in conjunction with the {ISignalService}. +/// @dev Ether is held by Bridges on L1 and by the EtherVault on L2, +/// not by token vaults. interface IBridge { struct Message { // Message ID. diff --git a/packages/protocol/contracts/common/AddressManager.sol b/packages/protocol/contracts/common/AddressManager.sol index 90abf9c727..48ef06b40d 100644 --- a/packages/protocol/contracts/common/AddressManager.sol +++ b/packages/protocol/contracts/common/AddressManager.sol @@ -10,18 +10,14 @@ import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { Proxied } from "./Proxied.sol"; -/** - * @title IAddressManager Interface - * @dev Specifies methods to manage address mappings for given domain-name - * pairs. - */ +/// @title IAddressManager +/// @notice Specifies methods to manage address mappings for given domain-name +/// pairs. interface IAddressManager { - /** - * @notice Set the address for a specific domain-name pair. - * @param domain The domain to which the address will be mapped. - * @param name The name to which the address will be mapped. - * @param newAddress The Ethereum address to be mapped. - */ + /// @notice Set the address for a specific domain-name pair. + /// @param domain The domain to which the address will be mapped. + /// @param name The name to which the address will be mapped. + /// @param newAddress The Ethereum address to be mapped. function setAddress( uint256 domain, bytes32 name, @@ -29,12 +25,10 @@ interface IAddressManager { ) external; - /** - * @notice Get the address mapped to a specific domain-name pair. - * @param domain The domain for which the address needs to be fetched. - * @param name The name for which the address needs to be fetched. - * @return Address associated with the domain-name pair. - */ + /// @notice Get the address mapped to a specific domain-name pair. + /// @param domain The domain for which the address needs to be fetched. + /// @param name The name for which the address needs to be fetched. + /// @return Address associated with the domain-name pair. function getAddress( uint256 domain, bytes32 name @@ -44,12 +38,8 @@ interface IAddressManager { returns (address); } -/** - * @title AddressManager - * @dev Manages a mapping of domain-name pairs to Ethereum addresses. - * Only the contract owner can modify these mappings. Address changes - * are emitted as events. - */ +/// @title AddressManager +/// @notice Manages a mapping of domain-name pairs to Ethereum addresses. contract AddressManager is OwnableUpgradeable, IAddressManager { mapping(uint256 => mapping(bytes32 => address)) private addresses; @@ -62,20 +52,12 @@ contract AddressManager is OwnableUpgradeable, IAddressManager { error EOA_OWNER_NOT_ALLOWED(); - /** - * @notice Initializes the owner for the upgradable contract. - */ + /// @notice Initializes the owner for the upgradable contract. function init() external initializer { OwnableUpgradeable.__Ownable_init(); } - /** - * @notice Maps a domain-name pair to an Ethereum address. - * @dev Can only be called by the contract owner. - * @param domain The domain to which the address will be mapped. - * @param name The name to which the address will be mapped. - * @param newAddress The Ethereum address to be mapped. - */ + /// @inheritdoc IAddressManager function setAddress( uint256 domain, bytes32 name, @@ -94,12 +76,7 @@ contract AddressManager is OwnableUpgradeable, IAddressManager { emit AddressSet(domain, name, newAddress, oldAddress); } - /** - * @notice Retrieves the address mapped to a domain-name pair. - * @param domain The domain for which the address needs to be fetched. - * @param name The name for which the address needs to be fetched. - * @return Address associated with the domain-name pair. - */ + /// @inheritdoc IAddressManager function getAddress( uint256 domain, bytes32 name @@ -113,8 +90,6 @@ contract AddressManager is OwnableUpgradeable, IAddressManager { } } -/** - * @title ProxiedAddressManager - * @dev Proxied version of the AddressManager contract. - */ +/// @title ProxiedAddressManager +/// @notice Proxied version of the AddressManager contract. contract ProxiedAddressManager is Proxied, AddressManager { } diff --git a/packages/protocol/contracts/common/AddressResolver.sol b/packages/protocol/contracts/common/AddressResolver.sol index d3f241a0c0..ad69c20f5a 100644 --- a/packages/protocol/contracts/common/AddressResolver.sol +++ b/packages/protocol/contracts/common/AddressResolver.sol @@ -9,13 +9,11 @@ pragma solidity ^0.8.20; import { IAddressManager } from "./AddressManager.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -/** - * @title AddressResolver - * @notice This contract acts as a bridge for name-to-address resolution. - * It delegates the resolution to the AddressManager. By separating the logic, - * we can maintain flexibility in address management without affecting the - * resolving process. - */ +/// @title AddressResolver +/// @notice This contract acts as a bridge for name-to-address resolution. +/// It delegates the resolution to the AddressManager. By separating the logic, +/// we can maintain flexibility in address management without affecting the +/// resolving process. abstract contract AddressResolver { IAddressManager internal _addressManager; @@ -27,22 +25,19 @@ abstract contract AddressResolver { error RESOLVER_INVALID_ADDR(); error RESOLVER_ZERO_ADDR(uint256 chainId, bytes32 name); - /** - * @dev Modifier that ensures the caller is the resolved address of a given - * name. - * @param name The name to check against. - */ + /// @dev Modifier that ensures the caller is the resolved address of a given + /// name. + /// @param name The name to check against. modifier onlyFromNamed(bytes32 name) { if (msg.sender != resolve(name, true)) revert RESOLVER_DENIED(); _; } - /** - * @dev Modifier that ensures the caller is one of the resolved addresses of - * given names. - * @param name1 The first name to check against. - * @param name2 The second name to check against. - */ + /// @dev Modifier that ensures the caller is one of the resolved addresses + /// of + /// given names. + /// @param name1 The first name to check against. + /// @param name2 The second name to check against. modifier onlyFromNamed2(bytes32 name1, bytes32 name2) { if ( msg.sender != resolve(name1, true) @@ -51,13 +46,12 @@ abstract contract AddressResolver { _; } - /** - * @dev Modifier that ensures the caller is one of the resolved addresses of - * given names. - * @param name1 The first name to check against. - * @param name2 The second name to check against. - * @param name3 The third name to check against. - */ + /// @dev Modifier that ensures the caller is one of the resolved addresses + /// of + /// given names. + /// @param name1 The first name to check against. + /// @param name2 The second name to check against. + /// @param name3 The third name to check against. modifier onlyFromNamed3(bytes32 name1, bytes32 name2, bytes32 name3) { if ( msg.sender != resolve(name1, true) @@ -67,14 +61,13 @@ abstract contract AddressResolver { _; } - /** - * @dev Modifier that ensures the caller is one of the resolved addresses of - * given names. - * @param name1 The first name to check against. - * @param name2 The second name to check against. - * @param name3 The third name to check against. - * @param name4 The fourth name to check against. - */ + /// @dev Modifier that ensures the caller is one of the resolved addresses + /// of + /// given names. + /// @param name1 The first name to check against. + /// @param name2 The second name to check against. + /// @param name3 The third name to check against. + /// @param name4 The fourth name to check against. modifier onlyFromNamed4( bytes32 name1, bytes32 name2, @@ -90,13 +83,11 @@ abstract contract AddressResolver { _; } - /** - * @notice Resolves a name to its address on the current chain. - * @param name Name whose address is to be resolved. - * @param allowZeroAddress If set to true, does not throw if the resolved - * address is `address(0)`. - * @return addr Address associated with the given name. - */ + /// @notice Resolves a name to its address on the current chain. + /// @param name Name whose address is to be resolved. + /// @param allowZeroAddress If set to true, does not throw if the resolved + /// address is `address(0)`. + /// @return addr Address associated with the given name. function resolve( bytes32 name, bool allowZeroAddress @@ -109,15 +100,13 @@ abstract contract AddressResolver { return _resolve(block.chainid, name, allowZeroAddress); } - /** - * @notice Resolves a name to its address on a specified chain. - * @param chainId The chainId of interest. - * @param name Name whose address is to be resolved. - * @param allowZeroAddress If set to true, does not throw if the resolved - * address is `address(0)`. - * @return addr Address associated with the given name on the specified - * chain. - */ + /// @notice Resolves a name to its address on a specified chain. + /// @param chainId The chainId of interest. + /// @param name Name whose address is to be resolved. + /// @param allowZeroAddress If set to true, does not throw if the resolved + /// address is `address(0)`. + /// @return addr Address associated with the given name on the specified + /// chain. function resolve( uint256 chainId, bytes32 name, @@ -131,32 +120,26 @@ abstract contract AddressResolver { return _resolve(chainId, name, allowZeroAddress); } - /** - * @notice Fetch the AddressManager's address. - * @return The current address of the AddressManager. - */ + /// @notice Fetches the AddressManager's address. + /// @return The current address of the AddressManager. function addressManager() public view returns (address) { return address(_addressManager); } - /** - * @dev Initialization method for setting up AddressManager reference. - * @param addressManager_ Address of the AddressManager. - */ + /// @dev Initialization method for setting up AddressManager reference. + /// @param addressManager_ Address of the AddressManager. function _init(address addressManager_) internal virtual { if (addressManager_ == address(0)) revert RESOLVER_INVALID_ADDR(); _addressManager = IAddressManager(addressManager_); } - /** - * @dev Helper method to resolve name-to-address. - * @param chainId The chainId of interest. - * @param name Name whose address is to be resolved. - * @param allowZeroAddress If set to true, does not throw if the resolved - * address is `address(0)`. - * @return addr Address associated with the given name on the specified - * chain. - */ + /// @dev Helper method to resolve name-to-address. + /// @param chainId The chainId of interest. + /// @param name Name whose address is to be resolved. + /// @param allowZeroAddress If set to true, does not throw if the resolved + /// address is `address(0)`. + /// @return addr Address associated with the given name on the specified + /// chain. function _resolve( uint256 chainId, bytes32 name, diff --git a/packages/protocol/contracts/common/EssentialContract.sol b/packages/protocol/contracts/common/EssentialContract.sol index 52b58ff711..3778bddb24 100644 --- a/packages/protocol/contracts/common/EssentialContract.sol +++ b/packages/protocol/contracts/common/EssentialContract.sol @@ -13,27 +13,23 @@ import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import { AddressResolver } from "./AddressResolver.sol"; -/** - * @title EssentialContract - * @dev This contract serves as the foundational contract for core components. - * It combines reentrancy protection, ownership functionality, and - * address resolution. - */ +/// @title EssentialContract +/// @notice This contract serves as the base contract for many core components. abstract contract EssentialContract is ReentrancyGuardUpgradeable, OwnableUpgradeable, AddressResolver { - /** - * @notice Update the AddressManager's address. - * @param newAddressManager Address of the new AddressManager. - */ + /// @notice Sets a new address manager. + /// @param newAddressManager Address of the new address manager. function setAddressManager(address newAddressManager) external onlyOwner { if (newAddressManager == address(0)) revert RESOLVER_INVALID_ADDR(); _addressManager = IAddressManager(newAddressManager); emit AddressManagerChanged(newAddressManager); } + /// @notice Initializes the contract with an address manager. + /// @param _addressManager The address of the address manager. function _init(address _addressManager) internal virtual override { ReentrancyGuardUpgradeable.__ReentrancyGuard_init(); OwnableUpgradeable.__Ownable_init(); diff --git a/packages/protocol/contracts/common/IMintableERC20.sol b/packages/protocol/contracts/common/IMintableERC20.sol index 7483de830c..f3c8dc4c2b 100644 --- a/packages/protocol/contracts/common/IMintableERC20.sol +++ b/packages/protocol/contracts/common/IMintableERC20.sol @@ -9,31 +9,16 @@ pragma solidity ^0.8.20; import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -/** - * @title IMintableERC20 - * @dev Interface for ERC20 tokens with mint and burn functionality. - * - * This interface extends the standard IERC20Upgradeable interface with - * additional methods for minting and burning tokens. Contracts that - * implement this interface can mint new tokens to an account or - * burn tokens from an account. - */ +/// @title IMintableERC20 +/// @notice Interface for ERC20 tokens with mint and burn functionality. interface IMintableERC20 is IERC20Upgradeable { - /** - * @notice Creates `amount` tokens and assigns them to `account`. - * @dev This can increase the total supply of the token. - * - * @param account The account to receive the minted tokens. - * @param amount The amount of tokens to mint. - */ + /// @notice Mints `amount` tokens and assigns them to the `account` address. + /// @param account The account to receive the minted tokens. + /// @param amount The amount of tokens to mint. function mint(address account, uint256 amount) external; - /** - * @notice Destroys `amount` tokens from `from`. - * @dev This can decrease the total supply of the token. - * - * @param from The account from which the tokens will be burned. - * @param amount The amount of tokens to burn. - */ + /// @notice Burns `amount` tokens from the `from` address. + /// @param from The account from which the tokens will be burned. + /// @param amount The amount of tokens to burn. function burn(address from, uint256 amount) external; } diff --git a/packages/protocol/contracts/common/Proxied.sol b/packages/protocol/contracts/common/Proxied.sol index 173f51fba3..26b2472ae2 100644 --- a/packages/protocol/contracts/common/Proxied.sol +++ b/packages/protocol/contracts/common/Proxied.sol @@ -9,12 +9,10 @@ pragma solidity ^0.8.20; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -/** - * @title Proxied - * @dev This abstract contract extends Initializable from OpenZeppelin's - * upgradeable contracts library. It is intended to be used for proxy - * pattern implementations where constructors are non-traditional. - */ +/// @title Proxied +/// @dev This abstract contract extends Initializable from OpenZeppelin's +/// upgradeable contracts library. It is intended to be used for proxy pattern +/// implementations where constructors are non-traditional. abstract contract Proxied is Initializable { /// @custom:oz-upgrades-unsafe-allow constructor constructor() { diff --git a/packages/protocol/contracts/libs/Lib1559Math.sol b/packages/protocol/contracts/libs/Lib1559Math.sol index 9d555e4a0b..0ac8b76f01 100644 --- a/packages/protocol/contracts/libs/Lib1559Math.sol +++ b/packages/protocol/contracts/libs/Lib1559Math.sol @@ -10,32 +10,22 @@ import { LibFixedPointMath } from "../thirdparty/LibFixedPointMath.sol"; import { SafeCastUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; -/** - * @title Lib1559Math Library - * - * @dev This library provides a set of mathematical functions related to the - * EIP-1559 implementation. - * The logo at the top of the file represents branding or creative design but - * does not serve a functional purpose. - */ +/// @title Lib1559Math +/// @dev This library provides utilities related to the L2 EIP-1559 +/// implementation. library Lib1559Math { using SafeCastUpgradeable for uint256; - // Errors definitions error L2_1559_UNEXPECTED_CHANGE(uint64 expected, uint64 actual); error L2_1559_OUT_OF_STOCK(); - /** - * @dev Calculates xscale and yscale values used for pricing. - * - * @param xExcessMax The maximum excess value. - * @param price The current price. - * @param target The target gas value. - * @param ratio2x1x Expected ratio of gas price for two blocks. - * - * @return xscale Calculated x scale value. - * @return yscale Calculated y scale value. - */ + /// @dev Calculates xscale and yscale values used for pricing. + /// @param xExcessMax The maximum excess value. + /// @param price The current price. + /// @param target The target gas value. + /// @param ratio2x1x Expected ratio of gas price for two blocks. + /// @return xscale Calculated x scale value. + /// @return yscale Calculated y scale value. function calculateScales( uint64 xExcessMax, uint64 price, @@ -49,13 +39,14 @@ library Lib1559Math { assert(xExcessMax != 0); uint64 x = xExcessMax / 2; - // calculate xscale + // Calculate xscale xscale = LibFixedPointMath.MAX_EXP_INPUT / xExcessMax; - // calculate yscale + // Calculate yscale yscale = calculatePrice(xscale, price, x, target).toUint128(); - // Verify the gas price ratio + // Verify the gas price ratio between two blocks, one has + // target * 2 gas and the other one has target gas. uint256 price1x = calculatePrice(xscale, yscale, x, target); uint256 price2x = calculatePrice(xscale, yscale, x, target * 2); uint64 ratio = uint64((price2x * 10_000) / price1x); @@ -65,16 +56,12 @@ library Lib1559Math { } } - /** - * @dev Calculates the price based on provided scales. - * - * @param xscale The x scale value. - * @param yscale The y scale value. - * @param xExcess Current excess value. - * @param xPurchase Amount of gas purchased. - * - * @return The calculated price. - */ + /// @dev Calculates the price based on provided scales. + /// @param xscale The x scale value. + /// @param yscale The y scale value. + /// @param xExcess Current excess value. + /// @param xPurchase Amount of gas purchased. + /// @return The calculated price. function calculatePrice( uint128 xscale, uint128 yscale, @@ -92,15 +79,10 @@ library Lib1559Math { return (_after - _before) / _xPurchase / yscale; } - /** - * @dev Internal function to calculate Y based on provided x value and - * scale. - * - * @param x The x value. - * @param xscale The x scale value. - * - * @return The calculated y value. - */ + /// @dev Internal function to calculate y value based on x value and scale. + /// @param x The x value. + /// @param xscale The x scale value. + /// @return The calculated y value. function _calcY(uint256 x, uint128 xscale) private pure returns (uint256) { uint256 _x = x * xscale; if (_x >= LibFixedPointMath.MAX_EXP_INPUT) { diff --git a/packages/protocol/contracts/libs/LibAddress.sol b/packages/protocol/contracts/libs/LibAddress.sol index 13a542cc2d..56c4cff39d 100644 --- a/packages/protocol/contracts/libs/LibAddress.sol +++ b/packages/protocol/contracts/libs/LibAddress.sol @@ -6,29 +6,15 @@ pragma solidity ^0.8.20; -/** - * @title LibAddress Library - * @notice Provides utilities for address-related operations. - * - * This library offers a collection of methods to manage addresses in smart - * contracts. These methods allow for safely sending Ether and fetching the - * code hash of an address. - */ - +/// @title LibAddress +/// @dev Provides utilities for address-related operations. library LibAddress { - /** - * @dev Sends Ether to the specified address. - * It is recommended to avoid using `.transfer()` due to potential - * reentrancy issues. - * Reference: - * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now - * - * @param to The recipient address. - * @param amount The amount of Ether to send in wei. - * - * @notice If either the amount is zero or the recipient address is the zero - * address, the function will simply return. - */ + /// @dev Sends Ether to the specified address. It is recommended to avoid + /// using `.transfer()` due to potential reentrancy issues. + /// Reference: + /// https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now + /// @param to The recipient address. + /// @param amount The amount of Ether to send in wei. function sendEther(address to, uint256 amount) internal { // Check for zero-value or zero-address transactions if (amount == 0 || to == address(0)) return; diff --git a/packages/protocol/contracts/libs/LibBlockHeader.sol b/packages/protocol/contracts/libs/LibBlockHeader.sol index 8ec1b10ec2..b6d6b92c8f 100644 --- a/packages/protocol/contracts/libs/LibBlockHeader.sol +++ b/packages/protocol/contracts/libs/LibBlockHeader.sol @@ -8,36 +8,33 @@ pragma solidity ^0.8.20; import { LibRLPWriter } from "../thirdparty/LibRLPWriter.sol"; -/** - * @title BlockHeader Struct - * @notice Defines the data structure for an Ethereum block header. - */ +/// @dev Defines the data structure for an Ethereum block header. struct BlockHeader { - bytes32 parentHash; // Hash of the parent block. - bytes32 ommersHash; // Hash of the ommers data. - address beneficiary; // Address of the beneficiary (miner). - bytes32 stateRoot; // State root after applying the block's transactions. - bytes32 transactionsRoot; // Merkle root of the block's transactions. - bytes32 receiptsRoot; // Merkle root of the block's receipts. - bytes32[8] logsBloom; // Bloom filter for logs in the block. - uint256 difficulty; // Mining difficulty. - uint128 height; // Block number. - uint64 gasLimit; // Gas limit for the block. - uint64 gasUsed; // Total gas used by all transactions in the block. - uint64 timestamp; // Unix timestamp. - bytes extraData; // Extra data (e.g., miner's arbitrary data). - bytes32 mixHash; // Proof-of-Work related data. - uint64 nonce; // Proof-of-Work nonce. - uint256 baseFeePerGas; // Base fee per gas (introduced in EIP-1559). - bytes32 withdrawalsRoot; // Merkle root for withdrawals (introduced in - // EIP-4895). + bytes32 parentHash; + bytes32 ommersHash; + address beneficiary; + bytes32 stateRoot; + bytes32 transactionsRoot; + bytes32 receiptsRoot; + bytes32[8] logsBloom; + uint256 difficulty; + uint128 height; + uint64 gasLimit; + uint64 gasUsed; + uint64 timestamp; + bytes extraData; + bytes32 mixHash; + uint64 nonce; + uint256 baseFeePerGas; + bytes32 withdrawalsRoot; } -/** - * @title LibBlockHeader Library - * @notice Provides functions to handle Ethereum block headers. - */ +/// @title LibBlockHeader +/// @dev Provides utilities for Ethereum block headers. library LibBlockHeader { + /// @dev Returns the hash of a block header. + /// @param header The block header. + /// @return The hash of the block header. function hashBlockHeader(BlockHeader memory header) internal pure @@ -48,14 +45,10 @@ library LibBlockHeader { return keccak256(rlpHeader); } - /** - * @dev Constructs the RLP item list for a block header. - * Different Ethereum Improvement Proposals (EIPs) may add different fields, - * and this function accounts for those variations. - * @param header The block header. - * @param extraCapacity Additional capacity for the list. - * @return list The RLP item list for the block header. - */ + /// @dev Constructs the RLP item list for a block header. + /// @param header The block header. + /// @param extraCapacity Additional capacity for the list. + /// @return list The RLP item list for the block header. function _getBlockHeaderRLPItemsList( BlockHeader memory header, uint256 extraCapacity @@ -88,7 +81,7 @@ library LibBlockHeader { list[11] = LibRLPWriter.writeUint64(header.timestamp); list[12] = LibRLPWriter.writeBytes(header.extraData); list[13] = LibRLPWriter.writeHash(header.mixHash); - // According to the ethereum yellow paper, we should treat `nonce` + // According to the Ethereum yellow paper, we should treat `nonce` // as [8]byte when hashing the block. list[14] = LibRLPWriter.writeBytes(abi.encodePacked(header.nonce)); if (header.baseFeePerGas != 0) { diff --git a/packages/protocol/contracts/libs/LibMath.sol b/packages/protocol/contracts/libs/LibMath.sol index 7df318a68e..1de714ba33 100644 --- a/packages/protocol/contracts/libs/LibMath.sol +++ b/packages/protocol/contracts/libs/LibMath.sol @@ -6,32 +6,21 @@ pragma solidity ^0.8.20; -/** - * @title LibMath Library - * @notice This library offers additional math functions for uint256. - * @dev Libraries in Solidity are similar to classes of OOP languages. They - * provide functions that can be applied to variables in a more native way - * without actually having an instance of a library. - */ +/// @title LibMath +/// @dev This library offers additional math functions for uint256. library LibMath { - /** - * @notice Returns the smaller of the two given values. - * @dev Uses the ternary operator to determine and return the smaller value. - * @param a The first number to compare. - * @param b The second number to compare. - * @return The smaller of the two numbers. - */ + /// @dev Returns the smaller of the two given values. + /// @param a The first number to compare. + /// @param b The second number to compare. + /// @return The smaller of the two numbers. function min(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? b : a; } - /** - * @notice Returns the larger of the two given values. - * @dev Uses the ternary operator to determine and return the larger value. - * @param a The first number to compare. - * @param b The second number to compare. - * @return The larger of the two numbers. - */ + /// @dev Returns the larger of the two given values. + /// @param a The first number to compare. + /// @param b The second number to compare. + /// @return The larger of the two numbers. function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } diff --git a/packages/protocol/contracts/libs/LibTrieProof.sol b/packages/protocol/contracts/libs/LibTrieProof.sol index 22b900c1c2..1e76fcb30a 100644 --- a/packages/protocol/contracts/libs/LibTrieProof.sol +++ b/packages/protocol/contracts/libs/LibTrieProof.sol @@ -1,5 +1,8 @@ // SPDX-License-Identifier: MIT -// ASCII art representing the file header +// _____ _ _ _ _ +// |_ _|_ _(_) |_____ | | __ _| |__ ___ +// | |/ _` | | / / _ \ | |__/ _` | '_ (_-< +// |_|\__,_|_|_\_\___/ |____\__,_|_.__/__/ pragma solidity ^0.8.20; @@ -8,10 +11,13 @@ import { LibRLPWriter } from "../thirdparty/LibRLPWriter.sol"; import { LibSecureMerkleTrie } from "../thirdparty/LibSecureMerkleTrie.sol"; /** - * @title LibTrieProof Library - * @notice This library is used for verifying the proof of values within the + * This library is used for verifying the proof of values within the * storage trie of an Ethereum account. + * @title LibTrieProof */ +/// @title LibTrieProof +/// @dev This library is used for verifying the proof of values within the +/// storage trie of an Ethereum account. library LibTrieProof { // Constant defining the index for the storage hash in the RLP-encoded // account structure. @@ -19,18 +25,16 @@ library LibTrieProof { uint256 private constant ACCOUNT_FIELD_INDEX_STORAGE_HASH = 2; error INVALID_ACCOUNT_PROOF(); - /** - * @notice Verifies that the value of a specific slot in the storage of an - * account equals the given value. - * @param stateRoot The merkle root of the state tree. - * @param addr The address of the account. - * @param slot The specific slot within the storage of the contract. - * @param value The value to be verified against the proof. - * @param mkproof The concatenated proof containing both account and storage - * proofs. - * @return verified Boolean result indicating if the proof is valid. - */ + /// @dev Verifies that the value of a specific slot in the storage of an + /// account equals the given value. + /// @param stateRoot The merkle root of the state tree. + /// @param addr The address of the account. + /// @param slot The specific slot within the storage of the contract. + /// @param value The value to be verified against the proof. + /// @param mkproof The concatenated proof containing both account and + /// storage proofs. + /// @return verified Boolean result indicating if the proof is valid. function verifyWithFullMerkleProof( bytes32 stateRoot, address addr, diff --git a/packages/protocol/contracts/libs/LibUint512Math.sol b/packages/protocol/contracts/libs/LibUint512Math.sol index 2706238b9c..baf623c39e 100644 --- a/packages/protocol/contracts/libs/LibUint512Math.sol +++ b/packages/protocol/contracts/libs/LibUint512Math.sol @@ -25,19 +25,14 @@ pragma solidity ^0.8.20; -/** - * @title LibUint512Math Library - */ +/// @title LibUint512Math library LibUint512Math { - /** - * @notice Multiplies two uint256 numbers to return a 512-bit result. - * @dev This function utilizes inline assembly for optimization. - * Reference: https://xn--2-umb.com/17/full-mul/index.html - * @param a The first uint256 operand. - * @param b The second uint256 operand. - * @return r0 The lower 256 bits of the result. - * @return r1 The higher 256 bits of the result. - */ + /// @dev Multiplies two uint256 numbers to return a 512-bit result. + /// Taken from: https://xn--2-umb.com/17/full-mul/index.html + /// @param a The first uint256 operand. + /// @param b The second uint256 operand. + /// @return r0 The lower 256 bits of the result. + /// @return r1 The higher 256 bits of the result. function mul( uint256 a, uint256 b @@ -57,18 +52,15 @@ library LibUint512Math { } } - /** - * @notice Adds two 512-bit numbers represented by two pairs of uint256. - * @dev This function uses inline assembly for optimization. - * Reference: - * https://xn--2-umb.com/17/512-bit-division/#add-subtract-two-512-bit-numbers - * @param a0 The lower 256 bits of the first number. - * @param a1 The higher 256 bits of the first number. - * @param b0 The lower 256 bits of the second number. - * @param b1 The higher 256 bits of the second number. - * @return r0 The lower 256 bits of the result. - * @return r1 The higher 256 bits of the result. - */ + /// @dev Adds two 512-bit numbers represented by two pairs of uint256. + /// Taken from: + /// https://xn--2-umb.com/17/512-bit-division/#add-subtract-two-512-bit-numbers + /// @param a0 The lower 256 bits of the first number. + /// @param a1 The higher 256 bits of the first number. + /// @param b0 The lower 256 bits of the second number. + /// @param b1 The higher 256 bits of the second number. + /// @return r0 The lower 256 bits of the result. + /// @return r1 The higher 256 bits of the result. function add( uint256 a0, uint256 a1, diff --git a/packages/protocol/contracts/signal/ISignalService.sol b/packages/protocol/contracts/signal/ISignalService.sol index 8d30675d6b..f5c43c9241 100644 --- a/packages/protocol/contracts/signal/ISignalService.sol +++ b/packages/protocol/contracts/signal/ISignalService.sol @@ -7,27 +7,27 @@ pragma solidity ^0.8.20; -/** - * @title ISignalService - * @notice This interface defines methods for sending and verifying signals - * across chains. - */ +/// @title ISignalService +/// @notice The SignalService contract serves as a secure cross-chain message +/// passing system. It defines methods for sending and verifying signals with +/// merkle proofs. The trust assumption is that the target chain has secure +/// access to the merkle root (such as Taiko injects it in the anchor +/// transaction). With this, verifying a signal is reduced to simply verifying +/// a merkle proof. + interface ISignalService { - /** - * @notice Emit a signal by setting the specified key to a value of 1. - * @param signal The unique identifier for the signal to be emitted. - * @return storageSlot The location in storage where this signal is stored. - */ + /// @notice Send a signal (message) by setting the storage slot to a value + /// of 1. + /// @param signal The signal (message) to send. + /// @return storageSlot The location in storage where this signal is stored. function sendSignal(bytes32 signal) external returns (bytes32 storageSlot); - /** - * @notice Verifies if a particular signal has already been emitted. - * @param app The address that initiated the signal. - * @param signal The unique identifier for the signal to verify. - * @return True if the signal has been emitted, otherwise false. - */ + /// @notice Verifies if a particular signal has already been sent. + /// @param app The address that initiated the signal. + /// @param signal The signal (message) to send. + /// @return True if the signal has been sent, otherwise false. function isSignalSent( address app, bytes32 signal @@ -36,15 +36,14 @@ interface ISignalService { view returns (bool); - /** - * @notice Verifies if a signal has been acknowledged on the target chain. - * @param srcChainId The identifier for the source chain from which the - * signal originated. - * @param app The address that initiated the signal. - * @param signal The unique identifier for the signal to verify. - * @param proof Data proving the signal was emitted on the source chain. - * @return True if the signal has been acknowledged, otherwise false. - */ + /// @notice Verifies if a signal has been received on the target chain. + /// @param srcChainId The identifier for the source chain from which the + /// signal originated. + /// @param app The address that initiated the signal. + /// @param signal The signal (message) to send. + /// @param proof Merkle proof that the signal was persisted on the + /// source chain. + /// @return True if the signal has been received, otherwise false. function isSignalReceived( uint256 srcChainId, address app, diff --git a/packages/protocol/contracts/signal/SignalService.sol b/packages/protocol/contracts/signal/SignalService.sol index e2829fcde2..d45cc00ea6 100644 --- a/packages/protocol/contracts/signal/SignalService.sol +++ b/packages/protocol/contracts/signal/SignalService.sol @@ -1,6 +1,4 @@ // SPDX-License-Identifier: MIT - -// ASCII art or logo representing the contract or library. // _____ _ _ _ _ // |_ _|_ _(_) |_____ | | __ _| |__ ___ // | |/ _` | | / / _ \ | |__/ _` | '_ (_-< @@ -14,38 +12,8 @@ import { ICrossChainSync } from "../common/ICrossChainSync.sol"; import { ISignalService } from "./ISignalService.sol"; import { LibSecureMerkleTrie } from "../thirdparty/LibSecureMerkleTrie.sol"; -/** - * @title SignalService - * - * @dev The SignalService contract serves as a cross-chain signaling mechanism, - * allowing external entities to send and verify signals within the Ethereum - * ecosystem. A "signal" in this context refers to a form of on-chain message or - * flag that can be verified by other contracts or entities across different - * chains. Such a mechanism is essential for cross-chain operations where - * certain actions or states need to be validated across multiple blockchain - * networks. - * - * Signals are persisted on-chain using the `sendSignal` method, which sets a - * particular storage slot based on the sender's address and the signal itself. - * - * The contract also provides the ability to check whether a given signal was - * sent by a specific address using the `isSignalSent` method. Moreover, it - * offers cross-chain signal verification with the `isSignalReceived` method, - * ensuring a signal sent from a source chain can be validated on a destination - * chain. - * - * Internally, the SignalService contract utilizes Merkle trie proofs, provided - * by `LibSecureMerkleTrie`, to verify the inclusion of signals. - * - * Note: - * While sending and checking signals on the current chain is straightforward, - * cross-chain signal verification requires a proof of the signal's existence on - * the source chain. - * - * Important: - * Before deploying or upgrading, always ensure you're aware of the contract's - * nuances, and have appropriately set the security contact. - */ +/// @title SignalService +/// @notice See the documentation in {ISignalService} for more details. contract SignalService is ISignalService, EssentialContract { struct SignalProof { uint256 height; @@ -76,6 +44,7 @@ contract SignalService is ISignalService, EssentialContract { EssentialContract._init(_addressManager); } + /// @inheritdoc ISignalService function sendSignal(bytes32 signal) public validSignal(signal) @@ -87,6 +56,7 @@ contract SignalService is ISignalService, EssentialContract { } } + /// @inheritdoc ISignalService function isSignalSent( address app, bytes32 signal @@ -105,6 +75,7 @@ contract SignalService is ISignalService, EssentialContract { return value == 1; } + /// @inheritdoc ISignalService function isSignalReceived( uint256 srcChainId, address app, @@ -130,6 +101,11 @@ contract SignalService is ISignalService, EssentialContract { ); } + /// @notice Get the storage slot of the signal. + /// @param app The address that initiated the signal. + /// @param signal The signal to get the storage slot of. + /// @return signalSlot The unique storage slot of the signal which is + /// created by encoding the sender address with the signal (message). function getSignalSlot( address app, bytes32 signal @@ -138,18 +114,22 @@ contract SignalService is ISignalService, EssentialContract { pure returns (bytes32 signalSlot) { + // Equivalent to `keccak256(abi.encodePacked(app, signal))` assembly { - let ptr := mload(0x40) // Load the free memory pointer + // Load the free memory pointer + let ptr := mload(0x40) + // Store the app address and signal bytes32 value in the allocated + // memory mstore(ptr, app) mstore(add(ptr, 32), signal) + // Calculate the hash of the concatenated arguments using keccak256 signalSlot := keccak256(add(ptr, 12), 52) - mstore(0x40, add(ptr, 64)) // Update free memory pointer + // Update free memory pointer + mstore(0x40, add(ptr, 64)) } } } -/** - * @title ProxiedSignalService - * @dev Proxied version of the SignalService contract. - */ +/// @title ProxiedSignalService +/// @notice Proxied version of the SignalService contract. contract ProxiedSignalService is Proxied, SignalService { } diff --git a/packages/protocol/contracts/test/bridge/libs/TestLibBridgeProcess.sol b/packages/protocol/contracts/test/bridge/libs/TestLibBridgeProcess.sol deleted file mode 100644 index 909f968b8b..0000000000 --- a/packages/protocol/contracts/test/bridge/libs/TestLibBridgeProcess.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// _____ _ _ _ _ -// |_ _|_ _(_) |_____ | | __ _| |__ ___ -// | |/ _` | | / / _ \ | |__/ _` | '_ (_-< -// |_|\__,_|_|_\_\___/ |____\__,_|_.__/__/ - -pragma solidity ^0.8.20; - -import { EssentialContract } from "../../../common/EssentialContract.sol"; -import { LibBridgeProcess } from "../../../bridge/libs/LibBridgeProcess.sol"; -import { LibBridgeData } from "../../../bridge/libs/LibBridgeData.sol"; -import { IBridge } from "../../../bridge/IBridge.sol"; -import { AddressResolver } from "../../../common/AddressResolver.sol"; - -// TODO(roger): remove this file. If you need extra functionality in -// the Bridge contract, create a TestBridge.sol contract instead. -contract TestLibBridgeProcess is EssentialContract { - LibBridgeData.State public state; - - function init(address _addressManager) external initializer { - EssentialContract._init(_addressManager); - } - - function processMessage( - IBridge.Message calldata message, - bytes calldata proof - ) - public - payable - { - LibBridgeProcess.processMessage( - state, AddressResolver(this), message, proof - ); - } -} diff --git a/packages/protocol/test/ProverPool_Protocol_Interactions.t.sol b/packages/protocol/test/ProverPool_Protocol_Interactions.t.sol index 86a10cdba5..08a16c2dc2 100644 --- a/packages/protocol/test/ProverPool_Protocol_Interactions.t.sol +++ b/packages/protocol/test/ProverPool_Protocol_Interactions.t.sol @@ -213,7 +213,7 @@ contract TaikoL1ProverPool is TaikoL1TestBase { } } - function test_asigned_prover_distribution_if_prover_pool_is_full() + function test_assigned_prover_distribution_if_prover_pool_is_full() external { depositTaikoToken(Alice, 1000 * 1e8, 1000 ether); @@ -265,7 +265,7 @@ contract TaikoL1ProverPool is TaikoL1TestBase { printVariables(""); } - function test_asigned_prover_distribution_if_only_have_1_prover() + function test_assigned_prover_distribution_if_only_have_1_prover() external { depositTaikoToken(Alice, 1000 * 1e8, 1000 ether); @@ -379,7 +379,7 @@ contract TaikoL1ProverPool is TaikoL1TestBase { printVariables(""); } - function test_asigned_prover_distribution_if_prover_pool_is_not_full() + function test_assigned_prover_distribution_if_prover_pool_is_not_full() external { depositTaikoToken(Alice, 1000 * 1e8, 1000 ether);