diff --git a/foundry.toml b/foundry.toml index 281cbf2..bb20f4d 100644 --- a/foundry.toml +++ b/foundry.toml @@ -48,10 +48,10 @@ via_ir = false no_storage_caching = false no_rpc_rate_limit = false use_literal_content = false -bytecode_hash = "none" -cbor_metadata = false +bytecode_hash = "ipfs" +cbor_metadata = true sparse_mode = false -build_info = true +build_info = false [[profile.default.fs_permissions]] access = "read" @@ -62,18 +62,18 @@ chains = "all" endpoints = "all" [fmt] -line_length = 120 +line_length = 80 tab_width = 4 bracket_spacing = false int_types = "long" -multiline_func_header = "all" +multiline_func_header = "params_first" quote_style = "double" -number_underscore = "thousands" +number_underscore = "preserve" hex_underscore = "remove" -single_line_statement_blocks = "preserve" +single_line_statement_blocks = "multi" override_spacing = false -wrap_comments = true -ignore = ["libs/*","*.t.sol"] +wrap_comments = false +ignore = [] contract_new_lines = false sort_imports = true diff --git a/src/ERC20.sol b/src/ERC20.sol index e3df696..9906a98 100644 --- a/src/ERC20.sol +++ b/src/ERC20.sol @@ -7,17 +7,19 @@ pragma solidity >=0.8.0; /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /** - EVENTS -/*/ - + * EVENTS + * / + */ event Transfer(address indexed from, address indexed to, uint256 amount); - event Approval(address indexed owner, address indexed spender, uint256 amount); + event Approval( + address indexed owner, address indexed spender, uint256 amount + ); /** - METADATA STORAGE -/*/ - + * METADATA STORAGE + * / + */ string public name; string public symbol; @@ -25,9 +27,9 @@ abstract contract ERC20 { uint8 public immutable decimals; /** - ERC20 STORAGE -/*/ - + * ERC20 STORAGE + * / + */ uint256 public totalSupply; mapping(address => uint256) public balanceOf; @@ -35,9 +37,9 @@ abstract contract ERC20 { mapping(address => mapping(address => uint256)) public allowance; /** - EIP-2612 STORAGE -/*/ - + * EIP-2612 STORAGE + * / + */ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; @@ -45,14 +47,10 @@ abstract contract ERC20 { mapping(address => uint256) public nonces; /** - CONSTRUCTOR -/*/ - - constructor( - string memory _name, - string memory _symbol, - uint8 _decimals - ) { + * CONSTRUCTOR + * / + */ + constructor(string memory _name, string memory _symbol, uint8 _decimals) { name = _name; symbol = _symbol; decimals = _decimals; @@ -62,10 +60,13 @@ abstract contract ERC20 { } /** - ERC20 LOGIC -/*/ - - function approve(address spender, uint256 amount) public virtual returns (bool) { + * ERC20 LOGIC + * / + */ + function approve( + address spender, + uint256 amount + ) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); @@ -73,7 +74,10 @@ abstract contract ERC20 { return true; } - function transfer(address to, uint256 amount) public virtual returns (bool) { + function transfer( + address to, + uint256 amount + ) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user @@ -94,7 +98,9 @@ abstract contract ERC20 { ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. - if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; + if (allowed != type(uint256).max) { + allowance[from][msg.sender] = allowed - amount; + } balanceOf[from] -= amount; @@ -110,9 +116,9 @@ abstract contract ERC20 { } /** - EIP-2612 LOGIC -/*/ - + * EIP-2612 LOGIC + * / + */ function permit( address owner, address spender, @@ -151,7 +157,10 @@ abstract contract ERC20 { s ); - require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); + require( + recoveredAddress != address(0) && recoveredAddress == owner, + "INVALID_SIGNER" + ); allowance[recoveredAddress][spender] = value; } @@ -160,26 +169,29 @@ abstract contract ERC20 { } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { - return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); + return block.chainid == INITIAL_CHAIN_ID + ? INITIAL_DOMAIN_SEPARATOR + : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { - return - keccak256( - abi.encode( - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), - keccak256(bytes(name)), - keccak256("1"), - block.chainid, - address(this) - ) - ); + return keccak256( + abi.encode( + keccak256( + "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" + ), + keccak256(bytes(name)), + keccak256("1"), + block.chainid, + address(this) + ) + ); } /** - INTERNAL MINT/BURN LOGIC -/*/ - + * INTERNAL MINT/BURN LOGIC + * / + */ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; diff --git a/src/ERC6909.sol b/src/ERC6909.sol index e8ad552..0c8958a 100644 --- a/src/ERC6909.sol +++ b/src/ERC6909.sol @@ -4,29 +4,37 @@ pragma solidity >=0.8.0; /// @notice Minimalist and gas efficient standard ERC6909 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC6909.sol) abstract contract ERC6909 { - -// EVENTS - + // EVENTS - event OperatorSet(address indexed owner, address indexed operator, bool approved); + event OperatorSet( + address indexed owner, address indexed operator, bool approved + ); - event Approval(address indexed owner, address indexed spender, uint256 indexed id, uint256 amount); + event Approval( + address indexed owner, + address indexed spender, + uint256 indexed id, + uint256 amount + ); - event Transfer(address caller, address indexed from, address indexed to, uint256 indexed id, uint256 amount); + event Transfer( + address caller, + address indexed from, + address indexed to, + uint256 indexed id, + uint256 amount + ); - -// ERC6909 STORAGE - + // ERC6909 STORAGE mapping(address => mapping(address => bool)) public isOperator; mapping(address => mapping(uint256 => uint256)) public balanceOf; - mapping(address => mapping(address => mapping(uint256 => uint256))) public allowance; + mapping(address => mapping(address => mapping(uint256 => uint256))) public + allowance; - -// ERC6909 LOGIC - + // ERC6909 LOGIC function transfer( address receiver, @@ -50,7 +58,9 @@ abstract contract ERC6909 { ) public virtual returns (bool) { if (msg.sender != sender && !isOperator[sender][msg.sender]) { uint256 allowed = allowance[sender][msg.sender][id]; - if (allowed != type(uint256).max) allowance[sender][msg.sender][id] = allowed - amount; + if (allowed != type(uint256).max) { + allowance[sender][msg.sender][id] = allowed - amount; + } } balanceOf[sender][id] -= amount; @@ -74,7 +84,10 @@ abstract contract ERC6909 { return true; } - function setOperator(address operator, bool approved) public virtual returns (bool) { + function setOperator( + address operator, + bool approved + ) public virtual returns (bool) { isOperator[msg.sender][operator] = approved; emit OperatorSet(msg.sender, operator, approved); @@ -82,19 +95,19 @@ abstract contract ERC6909 { return true; } - -// ERC165 LOGIC - + // ERC165 LOGIC - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { - return - interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 - interfaceId == 0x0f632fb3; // ERC165 Interface ID for ERC6909 + function supportsInterface(bytes4 interfaceId) + public + view + virtual + returns (bool) + { + return interfaceId == 0x01ffc9a7 // ERC165 Interface ID for ERC165 + || interfaceId == 0x0f632fb3; // ERC165 Interface ID for ERC6909 } - -// INTERNAL MINT/BURN LOGIC - + // INTERNAL MINT/BURN LOGIC function _mint( address receiver, diff --git a/src/LibSort.sol b/src/LibSort.sol index 97789bf..d4a5182 100644 --- a/src/LibSort.sol +++ b/src/LibSort.sol @@ -112,7 +112,9 @@ library LibSort { break } - for { let stackBottom := mload(0x40) } iszero(eq(stack, stackBottom)) {} { + for { let stackBottom := mload(0x40) } iszero( + eq(stack, stackBottom) + ) {} { // Pop `l` and `h` from the stack. stack := sub(stack, 0x40) let l := mload(stack) @@ -256,31 +258,28 @@ library LibSort { /// @dev Returns whether `a` contains `needle`, and the index of `needle`. /// `index` precedence: equal to > nearest before > nearest after. - function searchSorted(uint256[] memory a, uint256 needle) - internal - pure - returns (bool found, uint256 index) - { + function searchSorted( + uint256[] memory a, + uint256 needle + ) internal pure returns (bool found, uint256 index) { (found, index) = _searchSorted(a, needle, 0); } /// @dev Returns whether `a` contains `needle`, and the index of `needle`. /// `index` precedence: equal to > nearest before > nearest after. - function searchSorted(int256[] memory a, int256 needle) - internal - pure - returns (bool found, uint256 index) - { + function searchSorted( + int256[] memory a, + int256 needle + ) internal pure returns (bool found, uint256 index) { (found, index) = _searchSorted(_toUints(a), uint256(needle), 1 << 255); } /// @dev Returns whether `a` contains `needle`, and the index of `needle`. /// `index` precedence: equal to > nearest before > nearest after. - function searchSorted(address[] memory a, address needle) - internal - pure - returns (bool found, uint256 index) - { + function searchSorted( + address[] memory a, + address needle + ) internal pure returns (bool found, uint256 index) { (found, index) = _searchSorted(_toUints(a), uint256(uint160(needle)), 0); } @@ -354,7 +353,11 @@ library LibSort { } /// @dev Returns whether the array is strictly ascending (sorted and uniquified). - function isSortedAndUniquified(uint256[] memory a) internal pure returns (bool result) { + function isSortedAndUniquified(uint256[] memory a) + internal + pure + returns (bool result) + { /// @solidity memory-safe-assembly assembly { result := 1 @@ -371,7 +374,11 @@ library LibSort { } /// @dev Returns whether the array is strictly ascending (sorted and uniquified). - function isSortedAndUniquified(int256[] memory a) internal pure returns (bool result) { + function isSortedAndUniquified(int256[] memory a) + internal + pure + returns (bool result) + { /// @solidity memory-safe-assembly assembly { result := 1 @@ -388,97 +395,92 @@ library LibSort { } /// @dev Returns whether the array is strictly ascending (sorted and uniquified). - function isSortedAndUniquified(address[] memory a) internal pure returns (bool result) { + function isSortedAndUniquified(address[] memory a) + internal + pure + returns (bool result) + { result = isSortedAndUniquified(_toUints(a)); } /// @dev Returns the sorted set difference of `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function difference(uint256[] memory a, uint256[] memory b) - internal - pure - returns (uint256[] memory c) - { + function difference( + uint256[] memory a, + uint256[] memory b + ) internal pure returns (uint256[] memory c) { c = _difference(a, b, 0); } /// @dev Returns the sorted set difference between `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function difference(int256[] memory a, int256[] memory b) - internal - pure - returns (int256[] memory c) - { + function difference( + int256[] memory a, + int256[] memory b + ) internal pure returns (int256[] memory c) { c = _toInts(_difference(_toUints(a), _toUints(b), 1 << 255)); } /// @dev Returns the sorted set difference between `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function difference(address[] memory a, address[] memory b) - internal - pure - returns (address[] memory c) - { + function difference( + address[] memory a, + address[] memory b + ) internal pure returns (address[] memory c) { c = _toAddresses(_difference(_toUints(a), _toUints(b), 0)); } /// @dev Returns the sorted set intersection between `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function intersection(uint256[] memory a, uint256[] memory b) - internal - pure - returns (uint256[] memory c) - { + function intersection( + uint256[] memory a, + uint256[] memory b + ) internal pure returns (uint256[] memory c) { c = _intersection(a, b, 0); } /// @dev Returns the sorted set intersection between `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function intersection(int256[] memory a, int256[] memory b) - internal - pure - returns (int256[] memory c) - { + function intersection( + int256[] memory a, + int256[] memory b + ) internal pure returns (int256[] memory c) { c = _toInts(_intersection(_toUints(a), _toUints(b), 1 << 255)); } /// @dev Returns the sorted set intersection between `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function intersection(address[] memory a, address[] memory b) - internal - pure - returns (address[] memory c) - { + function intersection( + address[] memory a, + address[] memory b + ) internal pure returns (address[] memory c) { c = _toAddresses(_intersection(_toUints(a), _toUints(b), 0)); } /// @dev Returns the sorted set union of `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function union(uint256[] memory a, uint256[] memory b) - internal - pure - returns (uint256[] memory c) - { + function union( + uint256[] memory a, + uint256[] memory b + ) internal pure returns (uint256[] memory c) { c = _union(a, b, 0); } /// @dev Returns the sorted set union of `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function union(int256[] memory a, int256[] memory b) - internal - pure - returns (int256[] memory c) - { + function union( + int256[] memory a, + int256[] memory b + ) internal pure returns (int256[] memory c) { c = _toInts(_union(_toUints(a), _toUints(b), 1 << 255)); } /// @dev Returns the sorted set union between `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function union(address[] memory a, address[] memory b) - internal - pure - returns (address[] memory c) - { + function union( + address[] memory a, + address[] memory b + ) internal pure returns (address[] memory c) { c = _toAddresses(_union(_toUints(a), _toUints(b), 0)); } @@ -487,7 +489,11 @@ library LibSort { /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Reinterpret cast to an uint256 array. - function _toUints(int256[] memory a) private pure returns (uint256[] memory casted) { + function _toUints(int256[] memory a) + private + pure + returns (uint256[] memory casted) + { /// @solidity memory-safe-assembly assembly { casted := a @@ -495,7 +501,11 @@ library LibSort { } /// @dev Reinterpret cast to an uint256 array. - function _toUints(address[] memory a) private pure returns (uint256[] memory casted) { + function _toUints(address[] memory a) + private + pure + returns (uint256[] memory casted) + { /// @solidity memory-safe-assembly assembly { // As any address written to memory will have the upper 96 bits @@ -506,7 +516,11 @@ library LibSort { } /// @dev Reinterpret cast to an int array. - function _toInts(uint256[] memory a) private pure returns (int256[] memory casted) { + function _toInts(uint256[] memory a) + private + pure + returns (int256[] memory casted) + { /// @solidity memory-safe-assembly assembly { casted := a @@ -514,7 +528,11 @@ library LibSort { } /// @dev Reinterpret cast to an address array. - function _toAddresses(uint256[] memory a) private pure returns (address[] memory casted) { + function _toAddresses(uint256[] memory a) + private + pure + returns (address[] memory casted) + { /// @solidity memory-safe-assembly assembly { casted := a @@ -536,11 +554,11 @@ library LibSort { /// @dev Returns whether `a` contains `needle`, and the index of `needle`. /// `index` precedence: equal to > nearest before > nearest after. - function _searchSorted(uint256[] memory a, uint256 needle, uint256 signed) - private - pure - returns (bool found, uint256 index) - { + function _searchSorted( + uint256[] memory a, + uint256 needle, + uint256 signed + ) private pure returns (bool found, uint256 index) { /// @solidity memory-safe-assembly assembly { let w := not(0) @@ -569,11 +587,11 @@ library LibSort { /// @dev Returns the sorted set difference of `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function _difference(uint256[] memory a, uint256[] memory b, uint256 signed) - private - pure - returns (uint256[] memory c) - { + function _difference( + uint256[] memory a, + uint256[] memory b, + uint256 signed + ) private pure returns (uint256[] memory c) { /// @solidity memory-safe-assembly assembly { let s := 0x20 @@ -611,11 +629,11 @@ library LibSort { /// @dev Returns the sorted set intersection between `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function _intersection(uint256[] memory a, uint256[] memory b, uint256 signed) - private - pure - returns (uint256[] memory c) - { + function _intersection( + uint256[] memory a, + uint256[] memory b, + uint256 signed + ) private pure returns (uint256[] memory c) { /// @solidity memory-safe-assembly assembly { let s := 0x20 @@ -648,11 +666,11 @@ library LibSort { /// @dev Returns the sorted set union of `a` and `b`. /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function _union(uint256[] memory a, uint256[] memory b, uint256 signed) - private - pure - returns (uint256[] memory c) - { + function _union( + uint256[] memory a, + uint256[] memory b, + uint256 signed + ) private pure returns (uint256[] memory c) { /// @solidity memory-safe-assembly assembly { let s := 0x20 diff --git a/src/MerkleProofLib.sol b/src/MerkleProofLib.sol index 967eb98..a8b1e3a 100644 --- a/src/MerkleProofLib.sol +++ b/src/MerkleProofLib.sol @@ -11,11 +11,11 @@ library MerkleProofLib { /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`. - function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) - internal - pure - returns (bool isValid) - { + function verify( + bytes32[] memory proof, + bytes32 root, + bytes32 leaf + ) internal pure returns (bool isValid) { /// @solidity memory-safe-assembly assembly { if mload(proof) { @@ -43,11 +43,11 @@ library MerkleProofLib { } /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`. - function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) - internal - pure - returns (bool isValid) - { + function verifyCalldata( + bytes32[] calldata proof, + bytes32 root, + bytes32 leaf + ) internal pure returns (bool isValid) { /// @solidity memory-safe-assembly assembly { if proof.length { @@ -115,7 +115,11 @@ library MerkleProofLib { // For the case where `proof.length + leaves.length == 1`. if iszero(flagsLength) { // `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`. - isValid := eq(mload(xor(leaves, mul(xor(proof, leaves), proofLength))), root) + isValid := + eq( + mload(xor(leaves, mul(xor(proof, leaves), proofLength))), + root + ) break } @@ -128,9 +132,9 @@ library MerkleProofLib { // Sometimes, a little memory expansion costs less than branching. // Should cost less, even with a high free memory offset of 0x7d00. leavesLength := shl(5, leavesLength) - for { let i := 0 } iszero(eq(i, leavesLength)) { i := add(i, 0x20) } { - mstore(add(hashesFront, i), mload(add(leaves, i))) - } + for { let i := 0 } iszero(eq(i, leavesLength)) { + i := add(i, 0x20) + } { mstore(add(hashesFront, i), mload(add(leaves, i))) } // Compute the back of the hashes. let hashesBack := add(hashesFront, leavesLength) // This is the end of the memory for the queue. @@ -205,7 +209,8 @@ library MerkleProofLib { /// @solidity memory-safe-assembly assembly { // If the number of flags is correct. - for {} eq(add(leaves.length, proof.length), add(flags.length, 1)) {} { + for {} eq(add(leaves.length, proof.length), add(flags.length, 1)) {} + { // For the case where `proof.length + leaves.length == 1`. if iszero(flags.length) { // `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`. diff --git a/src/Owned.sol b/src/Owned.sol index 3813f4e..210ae03 100644 --- a/src/Owned.sol +++ b/src/Owned.sol @@ -4,14 +4,11 @@ pragma solidity >=0.8.0; /// @notice Simple single owner authorization mixin. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol) abstract contract Owned { - -// EVENTS + // EVENTS event OwnershipTransferred(address indexed user, address indexed newOwner); - -// OWNERSHIP STORAGE - + // OWNERSHIP STORAGE address public owner; @@ -21,9 +18,7 @@ abstract contract Owned { _; } - -// CONSTRUCTOR - + // CONSTRUCTOR constructor(address _owner) { owner = _owner; @@ -31,9 +26,7 @@ abstract contract Owned { emit OwnershipTransferred(address(0), _owner); } - -// OWNERSHIP LOGIC - + // OWNERSHIP LOGIC function transferOwnership(address newOwner) public virtual onlyOwner { owner = newOwner; diff --git a/src/SafeTransferLib.sol b/src/SafeTransferLib.sol index 1954aa5..478b2a9 100644 --- a/src/SafeTransferLib.sol +++ b/src/SafeTransferLib.sol @@ -42,31 +42,40 @@ library SafeTransferLib { let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. - mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument. - mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. + mstore( + freeMemoryPointer, + 0x23b872dd00000000000000000000000000000000000000000000000000000000 + ) + mstore( + add(freeMemoryPointer, 4), + and(from, 0xffffffffffffffffffffffffffffffffffffffff) + ) // Append and mask the "from" argument. + mstore( + add(freeMemoryPointer, 36), + and(to, 0xffffffffffffffffffffffffffffffffffffffff) + ) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. - success := and( - // Set success to whether the call reverted, if not we check it either - // returned exactly 1 (can't just be non-zero data), or had no return data. - or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), - // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. - // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. - // Counterintuitively, this call must be positioned second to the or() call in the - // surrounding and() call or else returndatasize() will be zero during the computation. - call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) - ) + success := + and( + // Set success to whether the call reverted, if not we check it either + // returned exactly 1 (can't just be non-zero data), or had no return data. + or( + and(eq(mload(0), 1), gt(returndatasize(), 31)), + iszero(returndatasize()) + ), + // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. + // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. + // Counterintuitively, this call must be positioned second to the or() call in the + // surrounding and() call or else returndatasize() will be zero during the computation. + call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) + ) } require(success, "TRANSFER_FROM_FAILED"); } - function safeTransfer( - ERC20 token, - address to, - uint256 amount - ) internal { + function safeTransfer(ERC20 token, address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly @@ -75,30 +84,36 @@ library SafeTransferLib { let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. - mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. + mstore( + freeMemoryPointer, + 0xa9059cbb00000000000000000000000000000000000000000000000000000000 + ) + mstore( + add(freeMemoryPointer, 4), + and(to, 0xffffffffffffffffffffffffffffffffffffffff) + ) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. - success := and( - // Set success to whether the call reverted, if not we check it either - // returned exactly 1 (can't just be non-zero data), or had no return data. - or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), - // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. - // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. - // Counterintuitively, this call must be positioned second to the or() call in the - // surrounding and() call or else returndatasize() will be zero during the computation. - call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) - ) + success := + and( + // Set success to whether the call reverted, if not we check it either + // returned exactly 1 (can't just be non-zero data), or had no return data. + or( + and(eq(mload(0), 1), gt(returndatasize(), 31)), + iszero(returndatasize()) + ), + // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. + // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. + // Counterintuitively, this call must be positioned second to the or() call in the + // surrounding and() call or else returndatasize() will be zero during the computation. + call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) + ) } require(success, "TRANSFER_FAILED"); } - function safeApprove( - ERC20 token, - address to, - uint256 amount - ) internal { + function safeApprove(ERC20 token, address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly @@ -107,20 +122,30 @@ library SafeTransferLib { let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. - mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. + mstore( + freeMemoryPointer, + 0x095ea7b300000000000000000000000000000000000000000000000000000000 + ) + mstore( + add(freeMemoryPointer, 4), + and(to, 0xffffffffffffffffffffffffffffffffffffffff) + ) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. - success := and( - // Set success to whether the call reverted, if not we check it either - // returned exactly 1 (can't just be non-zero data), or had no return data. - or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), - // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. - // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. - // Counterintuitively, this call must be positioned second to the or() call in the - // surrounding and() call or else returndatasize() will be zero during the computation. - call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) - ) + success := + and( + // Set success to whether the call reverted, if not we check it either + // returned exactly 1 (can't just be non-zero data), or had no return data. + or( + and(eq(mload(0), 1), gt(returndatasize(), 31)), + iszero(returndatasize()) + ), + // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. + // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. + // Counterintuitively, this call must be positioned second to the or() call in the + // surrounding and() call or else returndatasize() will be zero during the computation. + call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) + ) } require(success, "APPROVE_FAILED");