Last active
September 1, 2023 22:00
-
-
Save darkerego/edce02f936b6441b93e3ca66ae817780 to your computer and use it in GitHub Desktop.
Attempting to Revert Static Calls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import "contracts/simulateCalls/ViewStorageAccessible.sol"; | |
contract StaticCallCheck { | |
uint256 public stateVariable = 0; | |
uint256 public fakeTimestamp = 0; | |
uint256 public lol = 100; | |
uint public oldLol; | |
bool public lastSuccess ; | |
bytes4 constant CHANGE_LOL_SEL = bytes4(keccak256(bytes('changeLol()'))); | |
function changeLol() external returns(uint256 _lol) { | |
oldLol = lol; | |
require(msg.sender == address(this) && tx.origin != address(0), "?origin"); | |
lol += lol; | |
require(lol > oldLol, "Change not updated!"); | |
_lol = lol; | |
} | |
function bytesToUintAssembly(bytes memory input) public pure returns (uint256 result) { | |
assembly { | |
result := mload(add(input, 32)) | |
} | |
} | |
function stateChangingFunx() external returns(bool success) { | |
bytes memory currentLol; | |
(success, currentLol) = address(this).call{value: 0}(abi.encodeWithSelector(CHANGE_LOL_SEL)); | |
require(success, "The call failed!"); | |
lastSuccess = success; | |
lol += lol; | |
uint _currentLol = bytesToUintAssembly(currentLol); | |
if (lol == _currentLol) { | |
revert("The state did not change!"); | |
} else { | |
success = true; | |
} | |
} | |
function setStateVariable(uint256 newValue) public { | |
uint256 initialGas = gasleft(); | |
// Try to change state | |
stateVariable = newValue * 2; | |
uint256 finalGas = gasleft(); | |
uint256 gasConsumed = initialGas - finalGas; | |
// Mimic a timestamp change | |
fakeTimestamp = block.timestamp; | |
// Check if state changes were effective | |
if (stateVariable != newValue * 2 || fakeTimestamp != block.timestamp) { | |
revert("Possible staticcall detected via state changing variables"); | |
} | |
// Use gas consumption to further infer the type of call | |
if (gasConsumed == 0) { | |
revert("Possible staticcall detected via gas consumed"); | |
} | |
if (msg.sender == address(0) || tx.origin == address(0)) { | |
revert("Possible staticcall detected via send/origin"); | |
} | |
stateVariable = newValue; | |
require(this.stateChangingFunx(), "Static call!"); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment