diff --git a/src/main/resources/contract/solidity/0.8.26/DoubleBufferContract.sol b/src/main/resources/contract/solidity/0.8.26/DoubleBufferContract.sol new file mode 100644 index 00000000..e8e01198 --- /dev/null +++ b/src/main/resources/contract/solidity/0.8.26/DoubleBufferContract.sol @@ -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; + } +} \ No newline at end of file diff --git a/src/main/resources/contract/solidity/0.8.26/StorageContract.sol b/src/main/resources/contract/solidity/0.8.26/StorageContract.sol index 44138493..4719b10d 100644 --- a/src/main/resources/contract/solidity/0.8.26/StorageContract.sol +++ b/src/main/resources/contract/solidity/0.8.26/StorageContract.sol @@ -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); } @@ -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); } @@ -28,6 +30,7 @@ contract StorageContract { } function setBytes32(bytes32 _value) public { + require(_value != bytes32(0), "Invalid bytes32 value"); bytes32Slot.tstore(_value); } @@ -36,6 +39,7 @@ contract StorageContract { } function setUint256(uint256 _value) public { + require(_value <= type(uint256).max, "Invalid uint256 value"); uint256Slot.tstore(_value); } @@ -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); } @@ -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(); } diff --git a/src/main/resources/contract/solidity/0.8.26/TestDoubleBufferContract.sol b/src/main/resources/contract/solidity/0.8.26/TestDoubleBufferContract.sol new file mode 100644 index 00000000..013e229a --- /dev/null +++ b/src/main/resources/contract/solidity/0.8.26/TestDoubleBufferContract.sol @@ -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}(); + } +} \ No newline at end of file