Skip to content

Commit bc02c60

Browse files
committed
Fixed decimal value printing. Added callback operator to reentrancy
1 parent d641870 commit bc02c60

File tree

2 files changed

+101
-5
lines changed

2 files changed

+101
-5
lines changed

src/PoC.sol

+93-5
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,18 @@ contract PoC is Test, Tokens, Log {
117117
? tokensBalance[_user][_index][j].token.decimals()
118118
: 18;
119119
uint256 integer_part = balance / (10 ** d);
120-
uint256 fractional_part = balance % (10 ** d);
120+
string memory fractional_part_string;
121+
{
122+
uint256 fractional_part = balance % (10 ** d);
123+
string memory fractional_part_leading_zeros;
124+
125+
uint256 leading_zeros = d - (log10(fractional_part) + 1);
126+
for(uint256 i = 0; i < leading_zeros; i++) {
127+
fractional_part_leading_zeros = string.concat(fractional_part_leading_zeros, "0");
128+
}
129+
130+
fractional_part_string = string.concat(fractional_part_leading_zeros, toString(fractional_part));
131+
}
121132

122133
// Get token symbol
123134
string memory symbol = tokensBalance[_user][_index][j].token != IERC20(address(0x0))
@@ -128,10 +139,10 @@ contract PoC is Test, Tokens, Log {
128139
string memory template;
129140
if (logLevel == 1) {
130141
template = string.concat("%s\t|\t", symbol, "\t|\t%s.%s");
131-
_log(template, address(tokensBalance[_user][_index][j].token), integer_part, fractional_part);
142+
_log(template, address(tokensBalance[_user][_index][j].token), integer_part, fractional_part_string);
132143
} else if (logLevel == 0) {
133144
template = string.concat("--- ", symbol, " balance of [%s]:\t%s.%s", " ---");
134-
_log(template, resolvedAddress, integer_part, fractional_part);
145+
_log(template, resolvedAddress, integer_part, fractional_part_string);
135146
}
136147
}
137148
_log();
@@ -160,7 +171,18 @@ contract PoC is Test, Tokens, Log {
160171
? tokensBalance[_user][0][j].token.decimals()
161172
: 18;
162173
uint256 integer_part = abs_profit / (10 ** d);
163-
uint256 fractional_part = abs_profit % (10 ** d);
174+
string memory fractional_part_string;
175+
{
176+
uint256 fractional_part = abs_profit % (10 ** d);
177+
string memory fractional_part_leading_zeros;
178+
179+
uint256 leading_zeros = d - (log10(fractional_part) + 1);
180+
for(uint256 i = 0; i < leading_zeros; i++) {
181+
fractional_part_leading_zeros = string.concat(fractional_part_leading_zeros, "0");
182+
}
183+
184+
fractional_part_string = string.concat(fractional_part_leading_zeros, toString(fractional_part));
185+
}
164186

165187
// Get token symbol
166188
string memory symbol = tokensBalance[_user][0][j].token != IERC20(address(0x0))
@@ -170,7 +192,7 @@ contract PoC is Test, Tokens, Log {
170192
// Generate template string
171193
string memory template = string.concat("%s\t|\t", symbol, "\t|\t", sign, "%s.%s");
172194

173-
_log(template, address(tokensBalance[_user][0][j].token), integer_part, fractional_part);
195+
_log(template, address(tokensBalance[_user][0][j].token), integer_part, fractional_part_string);
174196
}
175197
_log();
176198
}
@@ -227,4 +249,70 @@ contract PoC is Test, Tokens, Log {
227249
if (uint8(b) < 10) return bytes1(uint8(b) + 0x30);
228250
else return bytes1(uint8(b) + 0x57);
229251
}
252+
253+
/**
254+
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
255+
* @notice Pulled from OpenZeppelin 5.0.2 Strings.sol library
256+
*/
257+
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
258+
function toString(uint256 value) internal pure returns (string memory) {
259+
unchecked {
260+
uint256 length = log10(value) + 1;
261+
string memory buffer = new string(length);
262+
uint256 ptr;
263+
/// @solidity memory-safe-assembly
264+
assembly {
265+
ptr := add(buffer, add(32, length))
266+
}
267+
while (true) {
268+
ptr--;
269+
/// @solidity memory-safe-assembly
270+
assembly {
271+
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
272+
}
273+
value /= 10;
274+
if (value == 0) break;
275+
}
276+
return buffer;
277+
}
278+
}
279+
280+
/**
281+
* @dev Return the log in base 10 of a positive value rounded towards zero.
282+
* @notice Pulled from OpenZeppelin 5.0.2 Math.sol library
283+
* Returns 0 if given 0.
284+
*/
285+
function log10(uint256 value) internal pure returns (uint256) {
286+
uint256 result = 0;
287+
unchecked {
288+
if (value >= 10 ** 64) {
289+
value /= 10 ** 64;
290+
result += 64;
291+
}
292+
if (value >= 10 ** 32) {
293+
value /= 10 ** 32;
294+
result += 32;
295+
}
296+
if (value >= 10 ** 16) {
297+
value /= 10 ** 16;
298+
result += 16;
299+
}
300+
if (value >= 10 ** 8) {
301+
value /= 10 ** 8;
302+
result += 8;
303+
}
304+
if (value >= 10 ** 4) {
305+
value /= 10 ** 4;
306+
result += 4;
307+
}
308+
if (value >= 10 ** 2) {
309+
value /= 10 ** 2;
310+
result += 2;
311+
}
312+
if (value >= 10 ** 1) {
313+
result += 1;
314+
}
315+
}
316+
return result;
317+
}
230318
}

src/reentrancy/Reentrancy.sol

+8
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ abstract contract Reentrancy {
7676
return this.onERC721Received.selector;
7777
}
7878

79+
/**
80+
* @dev Whenever an AAVE flashloan is executed
81+
*/
82+
function executeOperation(address, uint256, uint256, address, bytes calldata) external returns (bool) {
83+
_reentrancyCallback();
84+
return true;
85+
}
86+
7987
/**
8088
* @dev Fallback function called when no other functions match the function signature
8189
*/

0 commit comments

Comments
 (0)