Commit 3c308f34 authored by Matt Solomon's avatar Matt Solomon Committed by GitHub

feat: annotate assembly as memory safe (#10386)

parent 91a6fca3
...@@ -11,7 +11,7 @@ library TransientContext { ...@@ -11,7 +11,7 @@ library TransientContext {
/// @notice Gets the call depth. /// @notice Gets the call depth.
/// @return callDepth_ Current call depth. /// @return callDepth_ Current call depth.
function callDepth() internal view returns (uint256 callDepth_) { function callDepth() internal view returns (uint256 callDepth_) {
assembly { assembly ("memory-safe") {
callDepth_ := tload(CALL_DEPTH_SLOT) callDepth_ := tload(CALL_DEPTH_SLOT)
} }
} }
...@@ -20,7 +20,7 @@ library TransientContext { ...@@ -20,7 +20,7 @@ library TransientContext {
/// @param _slot Slot to get. /// @param _slot Slot to get.
/// @return value_ Transient value. /// @return value_ Transient value.
function get(bytes32 _slot) internal view returns (uint256 value_) { function get(bytes32 _slot) internal view returns (uint256 value_) {
assembly { assembly ("memory-safe") {
mstore(0, tload(CALL_DEPTH_SLOT)) mstore(0, tload(CALL_DEPTH_SLOT))
mstore(32, _slot) mstore(32, _slot)
value_ := tload(keccak256(0, 64)) value_ := tload(keccak256(0, 64))
...@@ -31,7 +31,7 @@ library TransientContext { ...@@ -31,7 +31,7 @@ library TransientContext {
/// @param _slot Slot to set. /// @param _slot Slot to set.
/// @param _value Value to set. /// @param _value Value to set.
function set(bytes32 _slot, uint256 _value) internal { function set(bytes32 _slot, uint256 _value) internal {
assembly { assembly ("memory-safe") {
mstore(0, tload(CALL_DEPTH_SLOT)) mstore(0, tload(CALL_DEPTH_SLOT))
mstore(32, _slot) mstore(32, _slot)
tstore(keccak256(0, 64), _value) tstore(keccak256(0, 64), _value)
...@@ -42,7 +42,7 @@ library TransientContext { ...@@ -42,7 +42,7 @@ library TransientContext {
/// This function can overflow. However, this is ok because there's still /// This function can overflow. However, this is ok because there's still
/// only one value stored per slot. /// only one value stored per slot.
function increment() internal { function increment() internal {
assembly { assembly ("memory-safe") {
tstore(CALL_DEPTH_SLOT, add(tload(CALL_DEPTH_SLOT), 1)) tstore(CALL_DEPTH_SLOT, add(tload(CALL_DEPTH_SLOT), 1))
} }
} }
...@@ -51,7 +51,7 @@ library TransientContext { ...@@ -51,7 +51,7 @@ library TransientContext {
/// This function can underflow. However, this is ok because there's still /// This function can underflow. However, this is ok because there's still
/// only one value stored per slot. /// only one value stored per slot.
function decrement() internal { function decrement() internal {
assembly { assembly ("memory-safe") {
tstore(CALL_DEPTH_SLOT, sub(tload(CALL_DEPTH_SLOT), 1)) tstore(CALL_DEPTH_SLOT, sub(tload(CALL_DEPTH_SLOT), 1))
} }
} }
......
...@@ -17,7 +17,7 @@ contract TransientContextTest is Test { ...@@ -17,7 +17,7 @@ contract TransientContextTest is Test {
/// @notice Tests that `callDepth()` outputs the corrects call depth. /// @notice Tests that `callDepth()` outputs the corrects call depth.
/// @param _callDepth Call depth to test. /// @param _callDepth Call depth to test.
function testFuzz_callDepth_succeeds(uint256 _callDepth) public { function testFuzz_callDepth_succeeds(uint256 _callDepth) public {
assembly { assembly ("memory-safe") {
tstore(sload(callDepthSlot.slot), _callDepth) tstore(sload(callDepthSlot.slot), _callDepth)
} }
assertEq(TransientContext.callDepth(), _callDepth); assertEq(TransientContext.callDepth(), _callDepth);
...@@ -27,7 +27,7 @@ contract TransientContextTest is Test { ...@@ -27,7 +27,7 @@ contract TransientContextTest is Test {
/// @param _startingCallDepth Starting call depth. /// @param _startingCallDepth Starting call depth.
function testFuzz_increment_succeeds(uint256 _startingCallDepth) public { function testFuzz_increment_succeeds(uint256 _startingCallDepth) public {
vm.assume(_startingCallDepth < type(uint256).max); vm.assume(_startingCallDepth < type(uint256).max);
assembly { assembly ("memory-safe") {
tstore(sload(callDepthSlot.slot), _startingCallDepth) tstore(sload(callDepthSlot.slot), _startingCallDepth)
} }
assertEq(TransientContext.callDepth(), _startingCallDepth); assertEq(TransientContext.callDepth(), _startingCallDepth);
...@@ -40,7 +40,7 @@ contract TransientContextTest is Test { ...@@ -40,7 +40,7 @@ contract TransientContextTest is Test {
/// @param _startingCallDepth Starting call depth. /// @param _startingCallDepth Starting call depth.
function testFuzz_decrement_succeeds(uint256 _startingCallDepth) public { function testFuzz_decrement_succeeds(uint256 _startingCallDepth) public {
vm.assume(_startingCallDepth > 0); vm.assume(_startingCallDepth > 0);
assembly { assembly ("memory-safe") {
tstore(sload(callDepthSlot.slot), _startingCallDepth) tstore(sload(callDepthSlot.slot), _startingCallDepth)
} }
assertEq(TransientContext.callDepth(), _startingCallDepth); assertEq(TransientContext.callDepth(), _startingCallDepth);
...@@ -56,7 +56,7 @@ contract TransientContextTest is Test { ...@@ -56,7 +56,7 @@ contract TransientContextTest is Test {
assertEq(TransientContext.get(_slot), 0); assertEq(TransientContext.get(_slot), 0);
bytes32 tSlot = keccak256(abi.encodePacked(TransientContext.callDepth(), _slot)); bytes32 tSlot = keccak256(abi.encodePacked(TransientContext.callDepth(), _slot));
assembly { assembly ("memory-safe") {
tstore(tSlot, _value) tstore(tSlot, _value)
} }
...@@ -70,7 +70,7 @@ contract TransientContextTest is Test { ...@@ -70,7 +70,7 @@ contract TransientContextTest is Test {
TransientContext.set(_slot, _value); TransientContext.set(_slot, _value);
bytes32 tSlot = keccak256(abi.encodePacked(TransientContext.callDepth(), _slot)); bytes32 tSlot = keccak256(abi.encodePacked(TransientContext.callDepth(), _slot));
uint256 tValue; uint256 tValue;
assembly { assembly ("memory-safe") {
tValue := tload(tSlot) tValue := tload(tSlot)
} }
assertEq(tValue, _value); assertEq(tValue, _value);
...@@ -145,7 +145,7 @@ contract TransientReentrancyAwareTest is TransientContextTest, TransientReentran ...@@ -145,7 +145,7 @@ contract TransientReentrancyAwareTest is TransientContextTest, TransientReentran
/// @param _value Value to test. /// @param _value Value to test.
function testFuzz_reentrantAware_succeeds(uint256 _callDepth, bytes32 _slot, uint256 _value) public { function testFuzz_reentrantAware_succeeds(uint256 _callDepth, bytes32 _slot, uint256 _value) public {
vm.assume(_callDepth < type(uint256).max); vm.assume(_callDepth < type(uint256).max);
assembly { assembly ("memory-safe") {
tstore(sload(callDepthSlot.slot), _callDepth) tstore(sload(callDepthSlot.slot), _callDepth)
} }
assertEq(TransientContext.callDepth(), _callDepth); assertEq(TransientContext.callDepth(), _callDepth);
...@@ -173,7 +173,7 @@ contract TransientReentrancyAwareTest is TransientContextTest, TransientReentran ...@@ -173,7 +173,7 @@ contract TransientReentrancyAwareTest is TransientContextTest, TransientReentran
public public
{ {
vm.assume(_callDepth < type(uint256).max - 1); vm.assume(_callDepth < type(uint256).max - 1);
assembly { assembly ("memory-safe") {
tstore(sload(callDepthSlot.slot), _callDepth) tstore(sload(callDepthSlot.slot), _callDepth)
} }
assertEq(TransientContext.callDepth(), _callDepth); assertEq(TransientContext.callDepth(), _callDepth);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment