Skip to content

Commit

Permalink
add Reentrancy Locks test solidity
Browse files Browse the repository at this point in the history
  • Loading branch information
wenlinlee committed Jul 12, 2024
1 parent 7db66df commit cc62750
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
contract DoubleBufferContract {
uint[] bufferA;
uint[] bufferB;

modifier nonreentrant(bytes32 key) {
assembly {
if tload(key) {revert(0, 0)}
tstore(key, 1)
}
_;
assembly {
tstore(key, 0)
}
}

bytes32 constant A_LOCK = keccak256("a");
bytes32 constant B_LOCK = keccak256("b");

function pushA() nonreentrant(A_LOCK) public payable {
bufferA.push(msg.value);
}

function popA() nonreentrant(A_LOCK) public {
require(bufferA.length > 0);

(bool success,) = msg.sender.call{value: bufferA[bufferA.length - 1]}("");
require(success);
bufferA.pop();
}

function pushB() nonreentrant(B_LOCK) public payable {
bufferB.push(msg.value);
}

function popB() nonreentrant(B_LOCK) public {
require(bufferB.length > 0);

(bool success,) = msg.sender.call{value: bufferB[bufferB.length - 1]}("");
require(success);
bufferB.pop();
}

function getBufferA() public view returns (uint256[] memory) {
return bufferA;
}

function getBufferB() public view returns (uint256[] memory) {
return bufferB;
}
}
10 changes: 10 additions & 0 deletions src/main/resources/contract/solidity/0.8.26/StorageContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ contract StorageContract {
StorageSlot.Int256SlotType private int256Slot = StorageSlot.asInt256(keccak256("int256_slot"));

function setAddress(address _value) public {
require(_value != address(0), "Invalid address");
addressSlot.tstore(_value);
}

Expand All @@ -20,6 +21,7 @@ contract StorageContract {
}

function setBoolean(bool _value) public {
require(_value == true || _value == false, "Input must be a boolean value");
booleanSlot.tstore(_value);
}

Expand All @@ -28,6 +30,7 @@ contract StorageContract {
}

function setBytes32(bytes32 _value) public {
require(_value != bytes32(0), "Invalid bytes32 value");
bytes32Slot.tstore(_value);
}

Expand All @@ -36,6 +39,7 @@ contract StorageContract {
}

function setUint256(uint256 _value) public {
require(_value <= type(uint256).max, "Invalid uint256 value");
uint256Slot.tstore(_value);
}

Expand All @@ -44,6 +48,7 @@ contract StorageContract {
}

function setInt256(int256 _value) public {
require(_value >= type(int256).min && _value < type(int256).max, "Invalid int256 value");
int256Slot.tstore(_value);
}

Expand All @@ -52,26 +57,31 @@ contract StorageContract {
}

function storeIntTest(int256 _value) public returns (int256) {
require(_value >= type(int256).min && _value < type(int256).max, "Invalid int256 value");
int256Slot.tstore(_value);
return int256Slot.tload();
}

function storeUintTest(uint256 _value) public returns (uint256) {
require(_value <= type(uint256).max, "Invalid uint256 value");
uint256Slot.tstore(_value);
return uint256Slot.tload();
}

function storeBytes32Test(bytes32 _value) public returns (bytes32) {
require(_value != bytes32(0), "Invalid bytes32 value");
bytes32Slot.tstore(_value);
return bytes32Slot.tload();
}

function storeBooleanTest(bool _value) public returns (bool) {
require(_value == true || _value == false, "Input must be a boolean value");
booleanSlot.tstore(_value);
return booleanSlot.tload();
}

function storeAddressTest(address _value) public returns (address) {
require(_value != address(0), "Invalid address");
addressSlot.tstore(_value);
return addressSlot.tload();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
pragma solidity ^0.8.0;

import "./DoubleBufferContract.sol";

contract TestDoubleBufferContract {
DoubleBufferContract public doubleBufferContract;

constructor() {
doubleBufferContract = new DoubleBufferContract();
}

function testReentrancyA() public {
doubleBufferContract.pushA{value: 1 ether}();
// 尝试再次调用pushA函数,应该被阻止
doubleBufferContract.pushA{value: 1 ether}();
}

function testReentrancyB() public {
doubleBufferContract.pushB{value: 1 ether}();
// 尝试再次调用pushB函数,应该被阻止
doubleBufferContract.pushB{value: 1 ether}();
}

receive() external payable {
doubleBufferContract.pushA{value: 1 ether}();
}
}

0 comments on commit cc62750

Please sign in to comment.