From bc02c60e584b22437f6f175412f7e6de736518a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Mu=C3=B1oz-McDonald?= Date: Tue, 23 Apr 2024 17:40:19 +0200 Subject: [PATCH 1/2] Fixed decimal value printing. Added callback operator to reentrancy --- src/PoC.sol | 98 +++++++++++++++++++++++++++++++++-- src/reentrancy/Reentrancy.sol | 8 +++ 2 files changed, 101 insertions(+), 5 deletions(-) diff --git a/src/PoC.sol b/src/PoC.sol index 1b2a7a0..ddece35 100644 --- a/src/PoC.sol +++ b/src/PoC.sol @@ -117,7 +117,18 @@ contract PoC is Test, Tokens, Log { ? tokensBalance[_user][_index][j].token.decimals() : 18; uint256 integer_part = balance / (10 ** d); - uint256 fractional_part = balance % (10 ** d); + string memory fractional_part_string; + { + uint256 fractional_part = balance % (10 ** d); + string memory fractional_part_leading_zeros; + + uint256 leading_zeros = d - (log10(fractional_part) + 1); + for(uint256 i = 0; i < leading_zeros; i++) { + fractional_part_leading_zeros = string.concat(fractional_part_leading_zeros, "0"); + } + + fractional_part_string = string.concat(fractional_part_leading_zeros, toString(fractional_part)); + } // Get token symbol string memory symbol = tokensBalance[_user][_index][j].token != IERC20(address(0x0)) @@ -128,10 +139,10 @@ contract PoC is Test, Tokens, Log { string memory template; if (logLevel == 1) { template = string.concat("%s\t|\t", symbol, "\t|\t%s.%s"); - _log(template, address(tokensBalance[_user][_index][j].token), integer_part, fractional_part); + _log(template, address(tokensBalance[_user][_index][j].token), integer_part, fractional_part_string); } else if (logLevel == 0) { template = string.concat("--- ", symbol, " balance of [%s]:\t%s.%s", " ---"); - _log(template, resolvedAddress, integer_part, fractional_part); + _log(template, resolvedAddress, integer_part, fractional_part_string); } } _log(); @@ -160,7 +171,18 @@ contract PoC is Test, Tokens, Log { ? tokensBalance[_user][0][j].token.decimals() : 18; uint256 integer_part = abs_profit / (10 ** d); - uint256 fractional_part = abs_profit % (10 ** d); + string memory fractional_part_string; + { + uint256 fractional_part = abs_profit % (10 ** d); + string memory fractional_part_leading_zeros; + + uint256 leading_zeros = d - (log10(fractional_part) + 1); + for(uint256 i = 0; i < leading_zeros; i++) { + fractional_part_leading_zeros = string.concat(fractional_part_leading_zeros, "0"); + } + + fractional_part_string = string.concat(fractional_part_leading_zeros, toString(fractional_part)); + } // Get token symbol string memory symbol = tokensBalance[_user][0][j].token != IERC20(address(0x0)) @@ -170,7 +192,7 @@ contract PoC is Test, Tokens, Log { // Generate template string string memory template = string.concat("%s\t|\t", symbol, "\t|\t", sign, "%s.%s"); - _log(template, address(tokensBalance[_user][0][j].token), integer_part, fractional_part); + _log(template, address(tokensBalance[_user][0][j].token), integer_part, fractional_part_string); } _log(); } @@ -227,4 +249,70 @@ contract PoC is Test, Tokens, Log { if (uint8(b) < 10) return bytes1(uint8(b) + 0x30); else return bytes1(uint8(b) + 0x57); } + + /** + * @dev Converts a `uint256` to its ASCII `string` decimal representation. + * @notice Pulled from OpenZeppelin 5.0.2 Strings.sol library + */ + bytes16 private constant HEX_DIGITS = "0123456789abcdef"; + function toString(uint256 value) internal pure returns (string memory) { + unchecked { + uint256 length = log10(value) + 1; + string memory buffer = new string(length); + uint256 ptr; + /// @solidity memory-safe-assembly + assembly { + ptr := add(buffer, add(32, length)) + } + while (true) { + ptr--; + /// @solidity memory-safe-assembly + assembly { + mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) + } + value /= 10; + if (value == 0) break; + } + return buffer; + } + } + + /** + * @dev Return the log in base 10 of a positive value rounded towards zero. + * @notice Pulled from OpenZeppelin 5.0.2 Math.sol library + * Returns 0 if given 0. + */ + function log10(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >= 10 ** 64) { + value /= 10 ** 64; + result += 64; + } + if (value >= 10 ** 32) { + value /= 10 ** 32; + result += 32; + } + if (value >= 10 ** 16) { + value /= 10 ** 16; + result += 16; + } + if (value >= 10 ** 8) { + value /= 10 ** 8; + result += 8; + } + if (value >= 10 ** 4) { + value /= 10 ** 4; + result += 4; + } + if (value >= 10 ** 2) { + value /= 10 ** 2; + result += 2; + } + if (value >= 10 ** 1) { + result += 1; + } + } + return result; + } } diff --git a/src/reentrancy/Reentrancy.sol b/src/reentrancy/Reentrancy.sol index 018cf7c..a2edc9c 100644 --- a/src/reentrancy/Reentrancy.sol +++ b/src/reentrancy/Reentrancy.sol @@ -76,6 +76,14 @@ abstract contract Reentrancy { return this.onERC721Received.selector; } + /** + * @dev Whenever an AAVE flashloan is executed + */ + function executeOperation(address, uint256, uint256, address, bytes calldata) external returns (bool) { + _reentrancyCallback(); + return true; + } + /** * @dev Fallback function called when no other functions match the function signature */ From 984efc82face38c1778f841eefc6499c41d2c015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Mu=C3=B1oz-McDonald?= Date: Tue, 23 Apr 2024 17:47:39 +0200 Subject: [PATCH 2/2] forge fmt --- src/PoC.sol | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/PoC.sol b/src/PoC.sol index ddece35..9f39ec1 100644 --- a/src/PoC.sol +++ b/src/PoC.sol @@ -123,7 +123,7 @@ contract PoC is Test, Tokens, Log { string memory fractional_part_leading_zeros; uint256 leading_zeros = d - (log10(fractional_part) + 1); - for(uint256 i = 0; i < leading_zeros; i++) { + for (uint256 i = 0; i < leading_zeros; i++) { fractional_part_leading_zeros = string.concat(fractional_part_leading_zeros, "0"); } @@ -177,10 +177,10 @@ contract PoC is Test, Tokens, Log { string memory fractional_part_leading_zeros; uint256 leading_zeros = d - (log10(fractional_part) + 1); - for(uint256 i = 0; i < leading_zeros; i++) { + for (uint256 i = 0; i < leading_zeros; i++) { fractional_part_leading_zeros = string.concat(fractional_part_leading_zeros, "0"); } - + fractional_part_string = string.concat(fractional_part_leading_zeros, toString(fractional_part)); } @@ -255,6 +255,7 @@ contract PoC is Test, Tokens, Log { * @notice Pulled from OpenZeppelin 5.0.2 Strings.sol library */ bytes16 private constant HEX_DIGITS = "0123456789abcdef"; + function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = log10(value) + 1;