Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: natspec and documentation improvements #41

Merged
merged 13 commits into from
Apr 17, 2024
36 changes: 18 additions & 18 deletions docs/src/content/intro/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,25 @@ Prophet presents a versatile and fully adaptable optimistic oracle solution, tra

## Deployments

The addresses of the contracts deployed on Optimism Goerli are listed below.

| Contract | Goerli |
*The addresses of the contracts deployed on Optimism Sepolia will be listed here.*
<!--
| Contract | Sepolia |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| [Oracle](/solidity/interfaces/core/IOracle.sol/interface.IOracle.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [AccountingExtension](/solidity/interfaces/extensions/IAccountingExtension.sol/interface.IAccountingExtension.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [BondEscalationAccounting](/solidity/interfaces/extensions/IBondEscalationAccounting.sol/interface.IBondEscalationAccounting.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [HttpRequestModule](/solidity/interfaces/modules/request/IHttpRequestModule.sol/interface.IHttpRequestModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [ContractCallRequestModule](/solidity/interfaces/modules/request/IContractCallRequestModule.sol/interface.IContractCallRequestModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [SparseMerkleTreeRequestModule](/solidity/interfaces/modules/request/ISparseMerkleTreeRequestModule.sol/interface.ISparseMerkleTreeRequestModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [BondedResponseModule](/solidity/interfaces/modules/response/IBondedResponseModule.sol/interface.IBondedResponseModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [BondedDisputeModule](/solidity/interfaces/modules/dispute/IBondedDisputeModule.sol/interface.IBondedDisputeModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [BondEscalationModule](/solidity/interfaces/modules/dispute/IBondEscalationModule.sol/interface.IBondEscalationModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [CircuitResolverModule](/solidity/interfaces/modules/dispute/ICircuitResolverModule.sol/interface.ICircuitResolverModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [RootVerificationModule](/solidity/interfaces/modules/dispute/IRootVerificationModule.sol/interface.IRootVerificationModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [ArbitratorModule](/solidity/interfaces/modules/resolution/IArbitratorModule.sol/interface.IArbitratorModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [BondEscalationResolutionModule](/solidity/interfaces/modules/resolution/IBondEscalationResolutionModule.sol/interface.IBondEscalationResolutionModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [ERC20ResolutionModule](/solidity/interfaces/modules/resolution/IERC20ResolutionModule.sol/interface.IERC20ResolutionModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [PrivateERC20ResolutionModule](/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol/interface.IPrivateERC20ResolutionModule.md) | [`0x0000000000000000000000000000000000000000`](https://goerli-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [Oracle](/solidity/interfaces/core/IOracle.sol/interface.IOracle.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [AccountingExtension](/solidity/interfaces/extensions/IAccountingExtension.sol/interface.IAccountingExtension.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [BondEscalationAccounting](/solidity/interfaces/extensions/IBondEscalationAccounting.sol/interface.IBondEscalationAccounting.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [HttpRequestModule](/solidity/interfaces/modules/request/IHttpRequestModule.sol/interface.IHttpRequestModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [ContractCallRequestModule](/solidity/interfaces/modules/request/IContractCallRequestModule.sol/interface.IContractCallRequestModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [SparseMerkleTreeRequestModule](/solidity/interfaces/modules/request/ISparseMerkleTreeRequestModule.sol/interface.ISparseMerkleTreeRequestModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [BondedResponseModule](/solidity/interfaces/modules/response/IBondedResponseModule.sol/interface.IBondedResponseModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [BondedDisputeModule](/solidity/interfaces/modules/dispute/IBondedDisputeModule.sol/interface.IBondedDisputeModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [BondEscalationModule](/solidity/interfaces/modules/dispute/IBondEscalationModule.sol/interface.IBondEscalationModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [CircuitResolverModule](/solidity/interfaces/modules/dispute/ICircuitResolverModule.sol/interface.ICircuitResolverModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [RootVerificationModule](/solidity/interfaces/modules/dispute/IRootVerificationModule.sol/interface.IRootVerificationModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [ArbitratorModule](/solidity/interfaces/modules/resolution/IArbitratorModule.sol/interface.IArbitratorModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [BondEscalationResolutionModule](/solidity/interfaces/modules/resolution/IBondEscalationResolutionModule.sol/interface.IBondEscalationResolutionModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [ERC20ResolutionModule](/solidity/interfaces/modules/resolution/IERC20ResolutionModule.sol/interface.IERC20ResolutionModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) |
| [PrivateERC20ResolutionModule](/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol/interface.IPrivateERC20ResolutionModule.md) | [`0x0000000000000000000000000000000000000000`](https://sepolia-optimism.etherscan.io/address/0x0000000000000000000000000000000000000000) | -->

## Licensing

Expand Down
23 changes: 23 additions & 0 deletions docs/src/content/modules/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,24 @@
# Modules

Here you can find the list and the details of each module available in Prophet
- [Request](./request.md)
- [Response](./response.md)
- [Dispute](./dispute.md)
- [Resolution](./resolution.md)
- [Finality](./finality.md)

## Common Parts

You can notice that many modules follow the same structure. This is because they all inherit from the `IModule` interface which defines the common functions and modifiers that all modules should have.

- `moduleName` is required to properly show the module in Prophet UI.
- `RequestParameters` is which parameters are required for the request to be processed with the module.
- `decodeRequestData` decodes the ABI encoded parameters using the `RequestParameters` struct and returns them as a list. This is useful for both on-chain and off-chain components.

## Best Practices

When building a module, keep in mind these tips to make the module predictable and easier to work with:

1. Always process the release and refund of the bond within the same module where the bonding initially occurs. This approach enhances composability and allows developers to concentrate on the logic specific to their module.
1. Typically, a module is designed to function independently. However, there are instances where multiple modules are developed in a manner that necessitates their joint use. For an example take a look at [SparseMerkleTreeModule](./request/sparse_merkle_tree_request_module.md) and [RootVerificationModule](./dispute/root_verification_module.md).
1. When feasible, avoid requiring users to interact directly with the module. Instead, route all calls via the oracle.
1 change: 1 addition & 0 deletions docs/src/content/modules/response.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ A Response module should take care of the following:
- Setting the rules for the responses, such as validations or deadlines
- Handling the rewards for proposing a valid response
- Applying the `onlyOracle` modifier to the hooks to secure them
- Releasing the bond if the response ended up being unutilized, meaning it's not accepted nor disputed

While developing a Response module, keep in mind that the criteria that is too narrow might result in a lack of responses, while criteria that is too broad might result in a large number of invalid responses.
2 changes: 2 additions & 0 deletions docs/src/content/modules/response/bonded_response_module.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The Bonded Response Module is a contract that allows users to propose a response

- `decodeRequestData`: Decodes request parameters.
- `propose`: Proposes a response for a request, bonding the proposer's tokens. A response cannot be proposed after the deadline or if an undisputed response has already been proposed.
- `releaseUnutilizedResponse`: Releases the proposer funds if the response is valid and it has not been used to finalize the request.
- `finalizeRequest`: Finalizes the request, paying the proposer of the final response.

### Request Parameters
Expand All @@ -25,3 +26,4 @@ The Bonded Response Module is a contract that allows users to propose a response

- **Early finalization**: It is possible for pre-dispute modules to atomically calculate the correct response on-chain, decide on the result of a dispute and finalize the request before its deadline.
- **Dispute window**: Prevents proposers from submitting a response 1 block before the deadline and finalizing it in the next block, leaving disputers no time to dispute the response.
- **Unutilized response**: A correct response that has not been used to finalize the request. Consider what happens when the first response to a request is disputed maliciously and someone sends a second response with the same content. In that case if the second response isn't disputed and the first one comes back from the dispute and is accepted as the final response, the second proposer should be able to get his bond back.
9 changes: 9 additions & 0 deletions natspec-smells.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* List of supported options: https://github.com/defi-wonderland/natspec-smells?tab=readme-ov-file#options
*/

/** @type {import('@defi-wonderland/natspec-smells').Config} */
module.exports = {
include: 'solidity/**/*.sol',
exclude: 'solidity/(test|scripts)/**/*'
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"package.json": "sort-package-json"
},
"dependencies": {
"@defi-wonderland/prophet-core-contracts": "0.0.0-f88b32e2",
"@defi-wonderland/prophet-core-contracts": "0.0.0-4d4a4487",
"@openzeppelin/contracts": "4.9.5",
"solmate": "https://github.com/transmissions11/solmate.git#bfc9c25865a274a7827fea5abf6e4fb64fc64e6c"
},
Expand Down
6 changes: 6 additions & 0 deletions solidity/contracts/extensions/AccountingExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,18 @@ contract AccountingExtension is IAccountingExtension {

/**
* @notice Checks that the caller is an allowed module used in the request.
* @param _requestId The request ID.
*/
modifier onlyAllowedModule(bytes32 _requestId) {
if (!ORACLE.allowedModule(_requestId, msg.sender)) revert AccountingExtension_UnauthorizedModule();
_;
}

/**
* @notice Checks if the user is either the requester or a proposer, or a disputer.
* @param _requestId The request ID.
* @param _user The address to check.
*/
modifier onlyParticipant(bytes32 _requestId, address _user) {
if (!ORACLE.isParticipant(_requestId, _user)) revert AccountingExtension_UnauthorizedUser();
_;
Expand Down
4 changes: 1 addition & 3 deletions solidity/contracts/libraries/MerkleLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@ library MerkleLib {
// ============= Structs ==============

/**
* @notice Struct representing incremental merkle tree. Contains current
* branch and the number of inserted leaves in the tree.
*
* @notice Struct representing incremental merkle tree. Contains current branch and the number of inserted leaves in the tree.
*/
struct Tree {
bytes32[TREE_DEPTH] branch;
Expand Down
4 changes: 4 additions & 0 deletions solidity/contracts/modules/dispute/BondEscalationModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ contract BondEscalationModule is Module, IBondEscalationModule {

/**
* @notice Checks the necessary conditions for pledging
* @param _disputeId The ID of the dispute to pledge for or against
* @param _request The request data
* @param _dispute The dispute data
* @param _forDispute Whether the pledge is for or against the dispute
* @return _params The decoded parameters for the request
*/
function _pledgeChecks(
Expand Down
5 changes: 3 additions & 2 deletions solidity/contracts/modules/dispute/CircuitResolverModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfac
import {ICircuitResolverModule} from '../../../interfaces/modules/dispute/ICircuitResolverModule.sol';

contract CircuitResolverModule is Module, ICircuitResolverModule {
constructor(IOracle _oracle) Module(_oracle) {}

/// @notice Keeps track of the correct responses to requests
mapping(bytes32 _requestId => bytes _correctResponse) internal _correctResponses;

constructor(IOracle _oracle) Module(_oracle) {}

/// @inheritdoc IModule
function moduleName() external pure returns (string memory _moduleName) {
return 'CircuitResolverModule';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu
/**
* @notice Pledges for or against a dispute
*
* @param _request The request being disputed
* @param _dispute The dispute to vote for or against
* @param _pledgeAmount The amount to pledge
* @param _pledgingFor Whether the pledger is pledging for or against the dispute
*/
Expand Down Expand Up @@ -314,6 +316,7 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu
* @param _disputeId The ID of the dispute
* @param _amountToRelease The amount to release
* @param _resolution The resolution of the dispute
* @param _params The request parameters
*/
function _claimPledge(
bytes32 _requestId,
Expand Down
11 changes: 4 additions & 7 deletions solidity/contracts/periphery/SparseMerkleTreeL32Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@ import {MerkleLib} from '../libraries/MerkleLib.sol';
contract SparseMerkleTreeL32Verifier is ITreeVerifier {
using MerkleLib for MerkleLib.Tree;

/// @notice The depth of the Merkle tree
uint256 internal constant _TREE_DEPTH = 32;
MerkleLib.Tree internal _tempTree;

constructor() {}
/// @notice A temporary tree created and cleaned up in the calculateRoot function
MerkleLib.Tree internal _tempTree;

/**
* @notice Calculates the Merkle root hash given a set of Merkle tree branches and merkle tree leaves count.
* @param _treeData The encoded Merkle tree data parameters for the tree verifier.
* @return _calculatedRoot The calculated Merkle root hash.
*/
/// @inheritdoc ITreeVerifier
function calculateRoot(
bytes memory _treeData,
bytes32[] memory _leavesToInsert
Expand Down
6 changes: 6 additions & 0 deletions solidity/interfaces/ITreeVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
pragma solidity ^0.8.19;

interface ITreeVerifier {
/**
* @notice Calculates the Merkle root hash given a set of Merkle tree branches and merkle tree leaves count.
* @param _treeData The encoded Merkle tree data parameters for the tree verifier.
* @param _leavesToInsert The array of leaves to insert into the Merkle tree.
* @return _calculatedRoot The calculated Merkle root hash.
*/
function calculateRoot(
bytes memory _treeData,
bytes32[] memory _leavesToInsert
Expand Down
4 changes: 4 additions & 0 deletions solidity/interfaces/extensions/IAccountingExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface IAccountingExtension {

/**
* @notice A payment between users has been made
* @param _requestId The ID of the request
* @param _beneficiary The user receiving the tokens
* @param _payer The user who is getting its tokens transferred
* @param _token The address of the token being transferred
Expand All @@ -43,6 +44,7 @@ interface IAccountingExtension {

/**
* @notice User's funds have been bonded
* @param _requestId The ID of the request
* @param _bonder The user who is getting its tokens bonded
* @param _token The address of the token being bonded
* @param _amount The amount of `_token` bonded
Expand All @@ -51,6 +53,7 @@ interface IAccountingExtension {

/**
* @notice User's funds have been released
* @param _requestId The ID of the request
* @param _beneficiary The user who is getting its tokens released
* @param _token The address of the token being released
* @param _amount The amount of `_token` released
Expand Down Expand Up @@ -90,6 +93,7 @@ interface IAccountingExtension {

/**
* @notice Returns the interface for the Oracle contract
* @return _oracle The Oracle address
*/
function ORACLE() external view returns (IOracle _oracle);

Expand Down
Loading
Loading