From d8e494263b206f71b0c5199a65d662c650fe7b82 Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Wed, 7 Dec 2022 16:59:36 +0100 Subject: [PATCH] Original codex answers --- src/auth/Auth.sol | 8 ++++ src/auth/Owned.sol | 9 ++++ src/auth/authorities/MultiRolesAuthority.sol | 8 ++++ src/auth/authorities/RolesAuthority.sol | 4 ++ src/mixins/ERC4626.sol | 33 ++++++++++++++ src/tokens/ERC1155.sol | 27 ++++++++++++ src/tokens/ERC20.sol | 23 ++++++++++ src/tokens/ERC721.sol | 45 ++++++++++++++++++++ src/tokens/WETH.sol | 8 ++++ src/utils/Bytes32AddressLib.sol | 8 ++++ src/utils/CREATE3.sol | 4 ++ src/utils/FixedPointMathLib.sol | 35 +++++++++++++++ src/utils/SSTORE2.sol | 16 +++++++ src/utils/SafeCastLib.sol | 44 +++++++++++++++++++ src/utils/SafeTransferLib.sol | 4 ++ src/utils/SignedWadMath.sol | 12 ++++++ 16 files changed, 288 insertions(+) diff --git a/src/auth/Auth.sol b/src/auth/Auth.sol index 3807ccda..b40ac4e4 100644 --- a/src/auth/Auth.sol +++ b/src/auth/Auth.sol @@ -27,6 +27,10 @@ abstract contract Auth { _; } + /** + * @notice Checks if the caller is authorized to call the given function. + * @dev This function checks if the caller is the owner or if the authority has granted the caller permission to call the given function. + */ function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) { Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas. @@ -45,6 +49,10 @@ abstract contract Auth { emit AuthorityUpdated(msg.sender, newAuthority); } + /** + * @notice This function allows the current owner to transfer ownership of the contract to a new owner. + * @dev The new owner must be provided as an address parameter. The function emits an OwnershipTransferred event. + */ function transferOwnership(address newOwner) public virtual requiresAuth { owner = newOwner; diff --git a/src/auth/Owned.sol b/src/auth/Owned.sol index e82b44d8..298e49ea 100644 --- a/src/auth/Owned.sol +++ b/src/auth/Owned.sol @@ -26,6 +26,10 @@ abstract contract Owned { CONSTRUCTOR //////////////////////////////////////////////////////////////*/ + /** + * @notice This function sets the owner of the contract to the address passed in as an argument. + * @dev The OwnershipTransferred event is emitted with the address 0 as the previous owner and the address passed in as the new owner. + */ constructor(address _owner) { owner = _owner; @@ -36,6 +40,11 @@ abstract contract Owned { OWNERSHIP LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice Transfers ownership of the contract to a new owner. + * @dev Only the current owner can call this function. + * @param newOwner The address of the new owner. + */ function transferOwnership(address newOwner) public virtual onlyOwner { owner = newOwner; diff --git a/src/auth/authorities/MultiRolesAuthority.sol b/src/auth/authorities/MultiRolesAuthority.sol index 3ff80bb0..b0803d1d 100644 --- a/src/auth/authorities/MultiRolesAuthority.sol +++ b/src/auth/authorities/MultiRolesAuthority.sol @@ -69,6 +69,10 @@ contract MultiRolesAuthority is Auth, Authority { CUSTOM TARGET AUTHORITY CONFIGURATION LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice Sets the custom authority for a given target address. + * @dev This function sets the custom authority for a given target address. It requires authentication and emits an event when the target custom authority is updated. + */ function setTargetCustomAuthority(address target, Authority customAuthority) public virtual requiresAuth { getTargetCustomAuthority[target] = customAuthority; @@ -107,6 +111,10 @@ contract MultiRolesAuthority is Auth, Authority { ROLE CAPABILITY CONFIGURATION LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice setRoleCapability() sets the capability of a role to execute a function. + * @dev This function requires authentication and sets the capability of a role to execute a function. It takes three parameters: role, functionSig, and enabled. If enabled is true, the role is given the capability to execute the function. Otherwise, the role is not given the capability to execute the function. + */ function setRoleCapability( uint8 role, bytes4 functionSig, diff --git a/src/auth/authorities/RolesAuthority.sol b/src/auth/authorities/RolesAuthority.sol index aa5cc71c..d78e9808 100644 --- a/src/auth/authorities/RolesAuthority.sol +++ b/src/auth/authorities/RolesAuthority.sol @@ -33,6 +33,10 @@ contract RolesAuthority is Auth, Authority { mapping(address => mapping(bytes4 => bytes32)) public getRolesWithCapability; + /** + * @notice This function checks if a user has a certain role. + * @dev This function takes an address of a user and a uint8 role as parameters and returns a boolean value. It uses the getUserRoles mapping to check if the user has the role. It shifts the uint256 value of the mapping to the right by the role parameter and checks if the result is not equal to 0. + */ function doesUserHaveRole(address user, uint8 role) public view virtual returns (bool) { return (uint256(getUserRoles[user]) >> role) & 1 != 0; } diff --git a/src/mixins/ERC4626.sol b/src/mixins/ERC4626.sol index af56c156..528bf8cc 100644 --- a/src/mixins/ERC4626.sol +++ b/src/mixins/ERC4626.sol @@ -119,8 +119,16 @@ abstract contract ERC4626 is ERC20 { ACCOUNTING LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice This function returns the total assets of the contract. + * @dev This function is a public view virtual function that returns the total assets of the contract. + */ function totalAssets() public view virtual returns (uint256); + /** + * @notice This function converts a given amount of assets to the corresponding amount of shares. + * @dev The function takes in a uint256 representing the amount of assets and returns a uint256 representing the amount of shares. The conversion is done by dividing the total assets by the total supply. + */ function convertToShares(uint256 assets) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. @@ -133,10 +141,20 @@ abstract contract ERC4626 is ERC20 { return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply); } + /** + * @notice This function allows users to preview the amount of shares they will receive when depositing a certain amount of assets. + * @dev This function takes in an amount of assets and returns the amount of shares that will be received when depositing that amount of assets. + */ function previewDeposit(uint256 assets) public view virtual returns (uint256) { return convertToShares(assets); } + /** + * @notice Calculates the amount of tokens that will be minted when the given number of shares is minted. + * @dev This function is view and virtual, meaning that it does not modify the state of the contract and can be used to simulate the minting of tokens. + * @param shares The number of shares to be minted. + * @return The amount of tokens that will be minted when the given number of shares is minted. + */ function previewMint(uint256 shares) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. @@ -149,6 +167,10 @@ abstract contract ERC4626 is ERC20 { return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets()); } + /** + * @notice This function allows users to preview the amount of assets they will receive when redeeming their shares. + * @dev This function takes in the number of shares as an argument and returns the amount of assets that will be received when redeeming the shares. + */ function previewRedeem(uint256 shares) public view virtual returns (uint256) { return convertToAssets(shares); } @@ -161,14 +183,25 @@ abstract contract ERC4626 is ERC20 { return type(uint256).max; } + /** + * @notice This function returns the maximum value of a uint256 type. + * @dev This function is used to return the maximum value of a uint256 type. It takes an address as an argument and returns the maximum value of a uint256 type.*/ function maxMint(address) public view virtual returns (uint256) { return type(uint256).max; } + /** + * @notice This function allows the owner to withdraw the maximum amount of assets from their account. + * @dev This function takes in the address of the owner and returns the maximum amount of assets that can be withdrawn. + */ function maxWithdraw(address owner) public view virtual returns (uint256) { return convertToAssets(balanceOf[owner]); } + /** + * @notice This function allows the owner to redeem the maximum amount of tokens from their balance. + * @dev The function takes in the address of the owner and returns the amount of tokens in their balance. + */ function maxRedeem(address owner) public view virtual returns (uint256) { return balanceOf[owner]; } diff --git a/src/tokens/ERC1155.sol b/src/tokens/ERC1155.sol index cff0f02d..1cef5d29 100644 --- a/src/tokens/ERC1155.sol +++ b/src/tokens/ERC1155.sol @@ -40,6 +40,9 @@ abstract contract ERC1155 { METADATA LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice This function returns a string representation of the given id. + * @dev This function is used to convert a uint256 id into a string representation. It is used to create a unique identifier for a given id.*/ function uri(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// @@ -52,6 +55,13 @@ abstract contract ERC1155 { emit ApprovalForAll(msg.sender, operator, approved); } + /** + * @notice This function allows a user to transfer a specific token from one address to another. + * @dev The function requires that the sender is either the from address or is approved for all of the from address. + * The balance of the from address is decreased by the amount and the balance of the to address is increased by the amount. + * The TransferSingle event is emitted. + * The function requires that the to address is either a valid address or an ERC1155TokenReceiver contract that implements the onERC1155Received function. + */ function safeTransferFrom( address from, address to, @@ -149,6 +159,10 @@ abstract contract ERC1155 { INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice This function mints a new token to the specified address. + * @dev This function mints a new token to the specified address. It also emits a TransferSingle event and checks that the recipient is a valid ERC1155TokenReceiver. + */ function _mint( address to, uint256 id, @@ -235,6 +249,10 @@ abstract contract ERC1155 { /// @notice A generic interface for a contract which properly accepts ERC1155 tokens. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155TokenReceiver { + /** + * @notice This function is triggered when an ERC1155 token is received. + * @dev This function is used to receive ERC1155 tokens. It takes in two addresses, two uint256 values, and a bytes calldata. It returns a bytes4 value. + */ function onERC1155Received( address, address, @@ -245,6 +263,15 @@ abstract contract ERC1155TokenReceiver { return ERC1155TokenReceiver.onERC1155Received.selector; } + /** + * @dev Function to receive a batch of ERC1155 tokens. + * @param _operator The address which called the function. + * @param _from The address of the sender. + * @param _ids An array of the ids of the tokens being sent. + * @param _values An array of the values of the tokens being sent. + * @param _data Any extra data with the transaction. + * @return The function selector of the ERC1155TokenReceiver.onERC1155BatchReceived function. + */ function onERC1155BatchReceived( address, address, diff --git a/src/tokens/ERC20.sol b/src/tokens/ERC20.sol index 96570446..2cf5ab86 100644 --- a/src/tokens/ERC20.sol +++ b/src/tokens/ERC20.sol @@ -73,6 +73,10 @@ abstract contract ERC20 { return true; } + /** + * @notice This function transfers an amount of tokens from the sender to the recipient. + * @dev The sender's balance is decreased and the recipient's balance is increased. + */ function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; @@ -113,6 +117,10 @@ abstract contract ERC20 { EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice This function permits a spender to withdraw from the owner's account, up to the given amount. + * @dev The function requires the owner to sign the transaction with their private key, and the signature is verified using the ecrecover function. The allowance is then set to the given value. + */ function permit( address owner, address spender, @@ -159,10 +167,21 @@ abstract contract ERC20 { emit Approval(owner, spender, value); } + /** + * DOMAIN_SEPARATOR + * + * @dev Returns the domain separator for the current chain. If the chainid is equal to the initial chain id, the initial domain separator is returned. Otherwise, the computeDomainSeparator() function is called. + * + * @return bytes32 The domain separator for the current chain. + */ function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } + /** + * @notice Computes the domain separator for the EIP712 domain + * @dev This function computes the domain separator for the EIP712 domain. It takes in the name, version, chainId, and verifyingContract and returns the domain separator as a bytes32. + */ function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( @@ -192,6 +211,10 @@ abstract contract ERC20 { emit Transfer(address(0), to, amount); } + /** + * @notice This function burns a given amount of tokens from a given address. + * @dev The function subtracts the given amount from the balance of the given address and from the total supply. + */ function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; diff --git a/src/tokens/ERC721.sol b/src/tokens/ERC721.sol index b47f2712..73d73c36 100644 --- a/src/tokens/ERC721.sol +++ b/src/tokens/ERC721.sol @@ -22,6 +22,10 @@ abstract contract ERC721 { string public symbol; + /** + * @notice This function returns a string memory associated with a given uint256 id. + * @dev This function is a public view virtual function that returns a string memory associated with a given uint256 id. + */ function tokenURI(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// @@ -32,6 +36,11 @@ abstract contract ERC721 { mapping(address => uint256) internal _balanceOf; + /** + * @notice ownerOf() function allows to retrieve the owner of a given token ID. + * @dev The function requires that the given token ID is minted and returns the address of the owner. + * If the token ID is not minted, an error message "NOT_MINTED" is thrown. + */ function ownerOf(uint256 id) public view virtual returns (address owner) { require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); } @@ -63,6 +72,11 @@ abstract contract ERC721 { ERC721 LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice This function allows the owner of an id to approve a spender to transfer the id. + * @dev The function requires that the msg.sender is either the owner of the id or is approved for all by the owner. + * If the requirements are met, the spender is set as the approved address for the id and an Approval event is emitted. + */ function approve(address spender, uint256 id) public virtual { address owner = _ownerOf[id]; @@ -79,6 +93,13 @@ abstract contract ERC721 { emit ApprovalForAll(msg.sender, operator, approved); } + /** + * @notice Transfers an NFT from one address to another. + * @dev The function requires that the sender is the owner of the NFT, or is approved by the owner. + * @param from The address of the current owner of the NFT. + * @param to The address of the new owner of the NFT. + * @param id The ID of the NFT to be transferred. + */ function transferFrom( address from, address to, @@ -108,6 +129,10 @@ abstract contract ERC721 { emit Transfer(from, to, id); } + /** + * @notice This function transfers an ERC721 token from one address to another. + * @dev This function requires that the recipient of the token is a valid ERC721 receiver. If the recipient is not a valid ERC721 receiver, the transfer will not be completed and an error will be thrown. + */ function safeTransferFrom( address from, address to, @@ -123,6 +148,14 @@ abstract contract ERC721 { ); } + /** + * @notice This function transfers an ERC721 token from one address to another. + * @dev The function requires that the recipient of the token is a valid ERC721 receiver. + * @param from The address of the sender. + * @param to The address of the recipient. + * @param id The ID of the ERC721 token. + * @param data Optional data to be passed to the recipient. + */ function safeTransferFrom( address from, address to, @@ -154,6 +187,10 @@ abstract contract ERC721 { INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice This function is used to mint a new token with a given id. + * @dev The function requires that the recipient address is not 0, and that the token has not already been minted. The balance of the recipient is incremented, and the owner of the token is set to the recipient. A Transfer event is emitted. + */ function _mint(address to, uint256 id) internal virtual { require(to != address(0), "INVALID_RECIPIENT"); @@ -169,6 +206,10 @@ abstract contract ERC721 { emit Transfer(address(0), to, id); } + /** + * @notice This function is used to burn a token with the given id. + * @dev This function requires that the owner of the token is not address(0). The balance of the owner is decreased by 1 and the owner of the token is set to address(0). The Transfer event is emitted. + */ function _burn(uint256 id) internal virtual { address owner = _ownerOf[id]; @@ -190,6 +231,10 @@ abstract contract ERC721 { INTERNAL SAFE MINT LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice This function mints a token to a specified address. + * @dev This function requires that the recipient of the token is a valid ERC721 token receiver. + */ function _safeMint(address to, uint256 id) internal virtual { _mint(to, id); diff --git a/src/tokens/WETH.sol b/src/tokens/WETH.sol index ddf9647d..036fbc10 100644 --- a/src/tokens/WETH.sol +++ b/src/tokens/WETH.sol @@ -15,12 +15,20 @@ contract WETH is ERC20("Wrapped Ether", "WETH", 18) { event Withdrawal(address indexed to, uint256 amount); + /** + * @notice This function allows users to deposit funds into the contract. + * @dev The function will mint the amount of tokens equal to the amount of funds deposited and emit a Deposit event. + */ function deposit() public payable virtual { _mint(msg.sender, msg.value); emit Deposit(msg.sender, msg.value); } + /** + * @notice This function allows a user to withdraw a specified amount of ETH from the contract. + * @dev The function first burns the amount of ETH from the user's balance, then emits a Withdrawal event, and finally sends the amount of ETH to the user's address. + */ function withdraw(uint256 amount) public virtual { _burn(msg.sender, amount); diff --git a/src/utils/Bytes32AddressLib.sol b/src/utils/Bytes32AddressLib.sol index 448fb759..df1433a0 100644 --- a/src/utils/Bytes32AddressLib.sol +++ b/src/utils/Bytes32AddressLib.sol @@ -4,10 +4,18 @@ pragma solidity >=0.8.0; /// @notice Library for converting between addresses and bytes32 values. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Bytes32AddressLib.sol) library Bytes32AddressLib { + /** + * @notice fromLast20Bytes() is a function that takes a bytes32 value and returns an address. + * @dev The function first converts the bytes32 value to a uint256, then to a uint160, and finally to an address. + */ function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) { return address(uint160(uint256(bytesValue))); } + /** + * @notice fillLast12Bytes() is a pure function that takes an address and returns the last 12 bytes of the address as a bytes32. + * @dev This function is used to convert an address to a bytes32. + */ function fillLast12Bytes(address addressValue) internal pure returns (bytes32) { return bytes32(bytes20(addressValue)); } diff --git a/src/utils/CREATE3.sol b/src/utils/CREATE3.sol index 0d5b341e..44fffc73 100644 --- a/src/utils/CREATE3.sol +++ b/src/utils/CREATE3.sol @@ -34,6 +34,10 @@ library CREATE3 { bytes32 internal constant PROXY_BYTECODE_HASH = keccak256(PROXY_BYTECODE); + /** + * @notice Deploys a new contract with pre-made bytecode via CREATE2. + * @dev Starts 32 bytes into the code to avoid copying the byte length. + */ function deploy( bytes32 salt, bytes memory creationCode, diff --git a/src/utils/FixedPointMathLib.sol b/src/utils/FixedPointMathLib.sol index 68877227..d41c6446 100644 --- a/src/utils/FixedPointMathLib.sol +++ b/src/utils/FixedPointMathLib.sol @@ -13,18 +13,33 @@ library FixedPointMathLib { uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. + /** + * @notice mulWadDown() multiplies two uint256 values and divides the result by WAD, rounding down. + * @dev mulWadDown() is an internal function that multiplies two uint256 values and divides the result by WAD, rounding down. + */ function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } + /** + * @notice mulWadUp() multiplies two uint256 values and divides the result by WAD, rounding up. + * @dev mulWadUp() is an internal function that multiplies two uint256 values and divides the result by WAD, rounding up. It is equivalent to (x * y) / WAD rounded up. + */ function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. } + /** + * @notice divWadDown() is a function that takes two uint256 parameters, x and y, and returns a uint256. It is equivalent to (x * WAD) / y rounded down. + * @dev divWadDown() is an internal, pure function that is used to calculate the result of (x * WAD) / y rounded down. It is used to ensure that calculations are accurate and consistent.*/ function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. } + /** + * @notice divWadUp() is a function that takes two uint256 parameters, x and y, and returns a uint256. It is equivalent to (x * WAD) / y rounded up. + * @dev divWadUp() is an internal, pure function. It uses mulDivUp() to calculate the result. + */ function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. } @@ -33,6 +48,10 @@ library FixedPointMathLib { LOW LEVEL FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ + /** + * @notice This function performs a multiplication and division operation on two uint256 values and a denominator. + * @dev This function requires that the denominator is not equal to 0 and that either y is equal to 0 or x is less than or equal to the maximum uint256 value divided by y. If either of these conditions are not met, the function will revert. The function then divides x * y by the denominator and returns the result. + */ function mulDivDown( uint256 x, uint256 y, @@ -161,6 +180,10 @@ library FixedPointMathLib { GENERAL NUMBER UTILITIES //////////////////////////////////////////////////////////////*/ + /** + * @notice This function implements the Babylonian method to calculate the square root of a given number. + * @dev This function is memory-safe and uses assembly to calculate the square root of a given number. It starts by setting the initial estimate to 181 and then checks if the number is greater than 256. If it is, it shifts the number right by the appropriate amount and shifts the initial estimate left by the same amount. It then checks if the number is in the range [256, 256*2^16) and if it is, it calculates the square root using the estimate 181 * (y + 65536)/2^18. Finally, it checks if the number is a perfect square and if it is, it returns the floor of the square root. + */ function sqrt(uint256 x) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { @@ -226,6 +249,10 @@ library FixedPointMathLib { } } + /** + * @notice This function performs a modulo operation on two uint256 values. + * @dev This function is not memory-safe and should be used with caution. If the second argument is zero, the function will return zero instead of reverting. + */ function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { @@ -235,6 +262,10 @@ library FixedPointMathLib { } } + /** + * @notice This function performs an unsafe division of two uint256 values. + * @dev This function should not be used in production code, as it will return 0 instead of reverting if y is zero. + */ function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { @@ -244,6 +275,10 @@ library FixedPointMathLib { } } + /** + * @notice This function performs a division operation on two uint256 values, x and y. + * @dev The function uses memory-safe assembly to ensure that the division is performed safely. It adds 1 to x * y if x % y > 0. Note that this will return 0 instead of reverting if y is zero. + */ function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { diff --git a/src/utils/SSTORE2.sol b/src/utils/SSTORE2.sol index 23d69803..bcace4e5 100644 --- a/src/utils/SSTORE2.sol +++ b/src/utils/SSTORE2.sol @@ -48,16 +48,32 @@ library SSTORE2 { READ LOGIC //////////////////////////////////////////////////////////////*/ + /** + * @notice Reads the bytecode of a given address + * @dev This function reads the bytecode of a given address and returns it as a bytes memory. + */ function read(address pointer) internal view returns (bytes memory) { return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET); } + /** + * @notice Reads the bytecode of a given address starting from a given offset. + * @dev This function reads the bytecode of a given address starting from a given offset and returns the bytes memory. + */ function read(address pointer, uint256 start) internal view returns (bytes memory) { start += DATA_OFFSET; return readBytecode(pointer, start, pointer.code.length - start); } + /** + * @notice Reads a range of bytes from the code of a given address. + * @dev This function reads a range of bytes from the code of a given address. It requires that the length of the code is greater than the end of the range. It returns the bytes read as a memory array. + * @param pointer The address from which to read the bytes. + * @param start The start of the range of bytes to read. + * @param end The end of the range of bytes to read. + * @return The bytes read as a memory array. + */ function read( address pointer, uint256 start, diff --git a/src/utils/SafeCastLib.sol b/src/utils/SafeCastLib.sol index ebbed225..31b22df4 100644 --- a/src/utils/SafeCastLib.sol +++ b/src/utils/SafeCastLib.sol @@ -5,66 +5,110 @@ pragma solidity >=0.8.0; /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeCastLib.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol) library SafeCastLib { + /** + * @notice safeCastTo248 is a function that takes a uint256 and returns a uint248. + * @dev The function requires that the uint256 is less than 2^248, and then casts it to a uint248. + */ function safeCastTo248(uint256 x) internal pure returns (uint248 y) { require(x < 1 << 248); y = uint248(x); } + /** + * @notice This function is used to safely cast a uint256 to a uint224. + * @dev This function requires that the uint256 is less than 1 << 224. If this is not the case, the function will revert. + */ function safeCastTo224(uint256 x) internal pure returns (uint224 y) { require(x < 1 << 224); y = uint224(x); } + /** + * @notice This function is used to safely cast a uint256 to a uint192. + * @dev This function requires that the uint256 is less than 1 << 192. If this is not the case, the function will revert. + */ function safeCastTo192(uint256 x) internal pure returns (uint192 y) { require(x < 1 << 192); y = uint192(x); } + /** + * @notice safeCastTo160() is a function that takes a uint256 and casts it to a uint160. + * @dev This function requires that the uint256 is less than 2^160. If this is not the case, the function will throw an error. + */ function safeCastTo160(uint256 x) internal pure returns (uint160 y) { require(x < 1 << 160); y = uint160(x); } + /** + * @notice safeCastTo128() is a function that takes a uint256 and casts it to a uint128. + * @dev This function requires that the uint256 is less than 2^128. If it is not, the function will throw an error. + */ function safeCastTo128(uint256 x) internal pure returns (uint128 y) { require(x < 1 << 128); y = uint128(x); } + /** + * @notice safeCastTo96() is a function that takes in a uint256 and returns a uint96. + * @dev The function requires that the input is less than 2^96, and then casts the input to a uint96. + */ function safeCastTo96(uint256 x) internal pure returns (uint96 y) { require(x < 1 << 96); y = uint96(x); } + /** + * @notice safeCastTo64() is a function that takes a uint256 and returns a uint64. + * @dev This function requires that the uint256 is less than 2^64. If the uint256 is greater than 2^64, the function will throw an error. The function casts the uint256 to a uint64. + */ function safeCastTo64(uint256 x) internal pure returns (uint64 y) { require(x < 1 << 64); y = uint64(x); } + /** + * @notice safeCastTo32 is a function that takes a uint256 and returns a uint32. + * @dev This function requires that the input is less than 2^32. If the input is greater than 2^32, the function will throw an error. The function casts the input to a uint32 and returns it. + */ function safeCastTo32(uint256 x) internal pure returns (uint32 y) { require(x < 1 << 32); y = uint32(x); } + /** + * @notice safeCastTo24() is a function that takes a uint256 and returns a uint24. + * @dev The function requires that the input is less than 2^24, and then casts the input to a uint24. + */ function safeCastTo24(uint256 x) internal pure returns (uint24 y) { require(x < 1 << 24); y = uint24(x); } + /** + * @notice safeCastTo16 is a function that takes a uint256 and casts it to a uint16. + * @dev The function requires that the uint256 is less than 1 << 16, and then casts it to a uint16. + */ function safeCastTo16(uint256 x) internal pure returns (uint16 y) { require(x < 1 << 16); y = uint16(x); } + /** + * @notice safeCastTo8() is a function that takes a uint256 and returns a uint8. + * @dev The function requires that the input is less than 1 << 8, and then casts the uint256 to a uint8. + */ function safeCastTo8(uint256 x) internal pure returns (uint8 y) { require(x < 1 << 8); diff --git a/src/utils/SafeTransferLib.sol b/src/utils/SafeTransferLib.sol index 7080fd83..458066f5 100644 --- a/src/utils/SafeTransferLib.sol +++ b/src/utils/SafeTransferLib.sol @@ -12,6 +12,10 @@ library SafeTransferLib { ETH OPERATIONS //////////////////////////////////////////////////////////////*/ + /** + * @notice This function is used to safely transfer ETH from one address to another. + * @dev This function uses memory-safe assembly to call the transfer function and store the success or failure of the transfer. If the transfer fails, an error is thrown. + */ function safeTransferETH(address to, uint256 amount) internal { bool success; diff --git a/src/utils/SignedWadMath.sol b/src/utils/SignedWadMath.sol index 4344285c..36f82b89 100644 --- a/src/utils/SignedWadMath.sol +++ b/src/utils/SignedWadMath.sol @@ -55,6 +55,10 @@ function unsafeWadDiv(int256 x, int256 y) pure returns (int256 r) { } } +/** + * @notice This function performs a multiplication of two integers and returns the result. + * @dev The function is memory-safe and uses assembly to ensure that the result is accurate. The result is scaled down by 1e18. + */ function wadMul(int256 x, int256 y) pure returns (int256 r) { /// @solidity memory-safe-assembly assembly { @@ -71,6 +75,10 @@ function wadMul(int256 x, int256 y) pure returns (int256 r) { } } +/** + * @notice This function divides two integers, x and y, and returns the result as an integer. + * @dev The function uses memory-safe assembly to ensure that the result is accurate and that no overflow occurs. The function checks that y is not 0 and that the result of the division is equal to x. If either of these conditions is not met, the function will revert. + */ function wadDiv(int256 x, int256 y) pure returns (int256 r) { /// @solidity memory-safe-assembly assembly { @@ -152,6 +160,10 @@ function wadExp(int256 x) pure returns (int256 r) { } } +/** + * @notice This function takes an int256 x and returns an int256 r. + * @dev This function converts x from 10**18 fixed point to 2**96 fixed point. It does this by multiplying by 2**96 / 10**18. It then reduces the range of x to (1, 2) * 2**96 and evaluates using a (8, 8)-term rational approximation. Finally, it multiplies by a scale factor, adds ln(2**96 / 10**18), adds k * ln(2), and multiplies by 10**18 / 2**96 = 5**18 >> 78. + */ function wadLn(int256 x) pure returns (int256 r) { unchecked { require(x > 0, "UNDEFINED");