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: improve LSP7 Natspec comments + add auto-generated docs #634

Merged
merged 2 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 86 additions & 74 deletions contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@ interface ILSP7DigitalAsset is IERC165, IERC725Y {
// --- Events

/**
* @dev Emitted when `amount` tokens is transferred from `from` to `to`.
* @param operator The address of operator sending tokens
* @param from The address which tokens are sent
* @param to The receiving address
* @param amount The amount of tokens transferred
* @param allowNonLSP1Recipient When set to TRUE, `to` may be any address but
* when set to FALSE `to` must be a contract that supports LSP1 UniversalReceiver
* @param data Additional data the caller wants included in the emitted event, and sent in the hooks to `from` and `to` addresses
* @dev Emitted when the `from` transferred successfully `amount` of tokens to `to`.
* @param operator The address of the operator that executed the transfer.
* @param from The address which tokens were sent from (balance decreased by `-amount`).
* @param to The address that received the tokens (balance increased by `+amount`).
* @param amount The amount of tokens transferred.
* @param allowNonLSP1Recipient if the transferred enforced the `to` recipient address to be a contract that implements the LSP1 standard or not.
* @param data Any additional data included by the caller during the transfer, and sent in the LSP1 hooks to the `from` and `to` addresses.
*/
event Transfer(
address indexed operator,
Expand All @@ -46,7 +45,7 @@ interface ILSP7DigitalAsset is IERC165, IERC725Y {
);

/**
* @dev Emitted when `tokenOwner` disables `operator` for `amount` tokens.
* @dev Emitted when `tokenOwner` disables `operator` for `amount` tokens and set its {`authorizedAmountFor(...)`} to `0`.
* @param operator The address revoked from operating
* @param tokenOwner The token owner
*/
Expand All @@ -55,78 +54,83 @@ interface ILSP7DigitalAsset is IERC165, IERC725Y {
// --- Token queries

/**
* @dev Returns the number of decimals used to get its user representation
* If the contract represents a NFT then 0 SHOULD be used, otherwise 18 is the common value
* @dev Returns the number of decimals used to get its user representation.
* If the asset contract has been set to be non-divisible via the `isNonDivisible_` parameter in
* the `constructor`, the decimals returned wiil be `0`. Otherwise `18` is the common value.
*
* NOTE: This information is only used for _display_ purposes: it in
* @custom:notice This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {balanceOf} and {transfer}.
*
* @return the number of decimals. If `0` is returned, the asset is non-divisible.
*/
function decimals() external view returns (uint8);

/**
* @dev Returns the number of existing tokens.
* @return The number of existing tokens
* @dev Returns the number of existing tokens that have been minted in this contract.
* @return The number of existing tokens.
*/
function totalSupply() external view returns (uint256);

// --- Token owner queries

/**
* @dev Returns the number of tokens owned by `tokenOwner`.
* @param tokenOwner The address to query
* @return The number of tokens owned by this address
* @dev Get the number of tokens owned by `tokenOwner`.
* If the token is divisible (the {decimals} function returns `18`), the amount returned should be divided
* by 1e18 to get a better picture of the actual balance of the `tokenOwner`.
*
* _Example:_
*
* ```
* balanceOf(someAddress) -> 42_000_000_000_000_000_000 / 1e18 = 42 tokens
* ```
*
* @param tokenOwner The address of the token holder to query the balance for.
* @return The amount of tokens owned by `tokenOwner`.
*/
function balanceOf(address tokenOwner) external view returns (uint256);

// --- Operator functionality

/**
* @param operator The address to authorize as an operator.
* @param amount The amount of tokens operator has access to.
* @dev Sets `amount` as the amount of tokens `operator` address has access to from callers tokens.
*
* To avoid front-running and Allowance Double-Spend Exploit when
* increasing or decreasing the authorized amount of an operator,
* it is advised to:
* 1. call {revokeOperator} first, and
* 2. then re-call {authorizeOperator} with the new amount
* @dev Sets an `amount` of tokens that an `operator` has access from the caller's balance (allowance). See {authorizedAmountFor}.
*
* for more information, see:
* https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/
*
*
* See {authorizedAmountFor}.
*
* Requirements
* @param operator The address to authorize as an operator.
* @param amount The allowance amount of tokens operator has access to.
*
* @custom:requirements
* - `operator` cannot be the zero address.
*
* Emits an {AuthorizedOperator} event.
* @custom:events {AuthorizedOperator} when allowance is given to a new operator or
* an existing operator's allowance is updated.
*/
function authorizeOperator(address operator, uint256 amount) external;

/**
* @param operator The address to revoke as an operator.
* @dev Removes `operator` address as an operator of callers tokens.
*
* See {authorizedAmountFor}.
* @dev Removes the `operator` address as an operator of callers tokens, disallowing it to send any amount of tokens
* on behalf of the token owner (the caller of the function `msg.sender`). See also {authorizedAmountFor}.
*
* Requirements
* @param operator The address to revoke as an operator.
*
* @custom:requirements
* - `operator` cannot be calling address.
* - `operator` cannot be the zero address.
*
* Emits a {RevokedOperator} event.
* @custom:events {RevokedOperator} event with address of the operator being revoked for the caller (token holder).
*/
function revokeOperator(address operator) external;

/**
* @param operator The address to query operator status for.
* @param tokenOwner The token owner.
* @return The amount of tokens `operator` address has access to from `tokenOwner`.
* @dev Returns amount of tokens `operator` address has access to from `tokenOwner`.
* Operators can send and burn tokens on behalf of their owners. The tokenOwner is their own
* operator.
* @dev Get the amount of tokens `operator` address has access to from `tokenOwner`.
* Operators can send and burn tokens on behalf of their owners.
*
* @param operator The operator's address to query the authorized amount for.
* @param tokenOwner The token owner that `operator` has allowance on.
*
* @return The amount of tokens the `operator`'s address has access on the `tokenOwner`'s balance.
*
* @custom:info If this function is called with the same address for `operator` and `tokenOwner`, it will simply read the `tokenOwner`'s balance
* (since a tokenOwner is its own operator).
*/
function authorizedAmountFor(
address operator,
Expand All @@ -136,25 +140,35 @@ interface ILSP7DigitalAsset is IERC165, IERC725Y {
// --- Transfer functionality

/**
* @param from The sending address.
* @param to The receiving address.
* @param amount The amount of tokens to transfer.
* @param allowNonLSP1Recipient When set to TRUE, to may be any address but
* when set to FALSE to must be a contract that supports LSP1 UniversalReceiver
* @param data Additional data the caller wants included in the emitted event, and sent in the hooks to `from` and `to` addresses.
*
* @dev Transfers `amount` of tokens from `from` to `to`. The `allowNonLSP1Recipient` parameter will be used
* when notifying the token sender and receiver.
* @dev Transfers an `amount` of tokens from the `from` address to the `to` address and notify both sender and recipients via the LSP1 {`universalReceiver(...)`} function.
* If the tokens are transferred by an operator on behalf of a token holder, the allowance for the operator will be decreased by `amount` once the token transfer
* has been completed (See {authorizedAmountFor}).
*
* Requirements:
* @param from The sender address.
* @param to The recipient address.
* @param amount The amount of tokens to transfer.
* @param allowNonLSP1Recipient When set to `true`, the `to` address CAN be any address. When set to `false`, the `to` address MUST be a contract that supports the LSP1 UniversalReceiver standard.
* @param data Any additional data the caller wants included in the emitted event, and sent in the hooks of the `from` and `to` addresses.
*
* @custom:requirements
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `amount` tokens must be owned by `from`.
* - If the caller is not `from`, it must be an operator for `from` with access to at least
* `amount` tokens.
* - `from` and `to` cannot be the same address (`from` cannot send tokens to itself).
* - `from` MUST have a balance of at least `amount` tokens.
* - If the caller is not `from`, it must be an operator for `from` with an allowance of at least `amount` of tokens.
*
* @custom:events
* - {Transfer} event when tokens get successfully transferred.
* - if the transfer is triggered by an operator, either the {AuthorizedOperator} event will be emitted with the updated allowance or the {RevokedOperator}
* event will be emitted if the operator has no more allowance left.
*
* @custom:hint The `allowNonLSP1Recipient` parameter **MUST be set to `true`** to transfer tokens to Externally Owned Accounts (EOAs)
* or contracts that do not implement the LSP1 Universal Receiver Standard. Otherwise the function will revert making the transfer fail.
*
* Emits a {Transfer} event.
* @custom:info if the `to` address is a contract that implements LSP1, it will always be notified via its `universalReceiver(...)` function, regardless if `allowNonLSP1Recipient` is set to `true` or `false`.
*
* @custom:warning Be aware that when either the sender or the recipient can have logic that revert in their `universalReceiver(...)` function when being notified.
* This even if the `allowNonLSP1Recipient` was set to `true`.
*/
function transfer(
address from,
Expand All @@ -165,26 +179,24 @@ interface ILSP7DigitalAsset is IERC165, IERC725Y {
) external;

/**
* @param from The list of sending addresses.
* @param to The list of receiving addresses.
* @param amount The amount of tokens to transfer.
* @param allowNonLSP1Recipient When set to TRUE, to may be any address but
* when set to FALSE to must be a contract that supports LSP1 UniversalReceiver
* @param data Additional data the caller wants included in the emitted event, and sent in the hooks to `from` and `to` addresses.
* @dev Same as {`transfer(...)`} but transfer multiple tokens based on the arrays of `from`, `to`, `amount`.
*
* @dev Transfers many tokens based on the list `from`, `to`, `amount`. If any transfer fails
* the call will revert.
* @custom:info If any transfer in the batch fail or revert, the whole call will revert.
*
* Requirements:
* @param from An array of sending addresses.
* @param to An array of receiving addresses.
* @param amount An array of amount of tokens to transfer for each `from -> to` transfer.
* @param allowNonLSP1Recipient For each transfer, when set to `true`, the `to` address CAN be any address. When set to `false`, the `to` address MUST be a contract that supports the LSP1 UniversalReceiver standard.
* @param data An array of additional data the caller wants included in the emitted event, and sent in the hooks to `from` and `to` addresses.
*
* - `from`, `to`, `amount` lists are the same length.
* @custom:requirements
* - `from`, `to`, `amount` lists MUST be of the same length.
* - no values in `from` can be the zero address.
* - no values in `to` can be the zero address.
* - each `amount` tokens must be owned by `from`.
* - If the caller is not `from`, it must be an operator for `from` with access to at least
* `amount` tokens.
* - each `amount` tokens MUST be owned by `from`.
* - for each transfer, if the caller is not `from`, it MUST be an operator for `from` with access to at least `amount` tokens.
*
* Emits {Transfer} events.
* @custom:events {Transfer} event **for each token transfer**.
*/
function transferBatch(
address[] memory from,
Expand Down
6 changes: 3 additions & 3 deletions contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import {LSP7DigitalAssetCore} from "./LSP7DigitalAssetCore.sol";
import {_INTERFACEID_LSP7} from "./LSP7Constants.sol";

/**
* @title LSP7DigitalAsset contract
* @title Implementation of a LSP7 Digital Asset, a contract that represents a fungible token.
* @author Matthew Stevens
* @dev Implementation of a LSP7 compliant contract.
*
* @dev Minting and transferring are supplied with a `uint256` amount.
* This implementation is agnostic to the way tokens are created.
* A supply mechanism has to be added in a derived contract using {_mint}
* For a generic mechanism, see {LSP7Mintable}.
Expand All @@ -44,7 +44,7 @@ abstract contract LSP7DigitalAsset is
}

/**
* @dev See {IERC165-supportsInterface}.
* @inheritdoc IERC165
*/
function supportsInterface(
bytes4 interfaceId
Expand Down
Loading
Loading