From 607629994e371d031493a9f3f789f2db36e46126 Mon Sep 17 00:00:00 2001 From: wenlinli <1574249665@qq.com> Date: Mon, 29 Jul 2024 19:30:05 +0800 Subject: [PATCH] add Reentrancy Locks test contract add update StorageContract.sol (#851) Co-authored-by: Kyon <32325790+kyonRay@users.noreply.github.com> --- .github/workflows/workflow.yml | 13 +++-- .../solidity/0.8.26/DoubleBufferContract.sol | 50 +++++++++++++++++++ .../solidity/0.8.26/StorageContract.sol | 15 ++++++ .../0.8.26/TestDoubleBufferContract.sol | 27 ++++++++++ 4 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/contract/solidity/0.8.26/DoubleBufferContract.sol create mode 100644 src/main/resources/contract/solidity/0.8.26/TestDoubleBufferContract.sol diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 2e4455e2..8ac222c3 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -44,14 +44,19 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04] - container: docker.io/centos:7 + os: [ ubuntu-20.04 ] + container: docker.io/centos:latest steps: - uses: actions/checkout@v2 with: fetch-depth: 5 - name: install CentOS dependencies - run: yum install -y epel-release centos-release-scl which git openssl-devel openssl wget + run: | + cd /etc/yum.repos.d/ + sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* + sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* + yum update -y + yum install -y which git openssl-devel openssl wget - name: Set up JDK 1.8 uses: actions/setup-java@v3 with: @@ -60,4 +65,4 @@ jobs: - name: run integration testing run: /bin/bash -x .ci/ci_check.sh - name: upload coverage - run: curl -LO https://codecov.io/bash && /bin/bash ./bash \ No newline at end of file + run: curl -LO https://codecov.io/bash && /bin/bash ./bash 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..2dcebe67 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,8 @@ contract StorageContract { } function setBoolean(bool _value) public { + require(_value == true, "Input must be a boolean value"); + require(_value == false, "Input must be a boolean value"); booleanSlot.tstore(_value); } @@ -28,6 +31,7 @@ contract StorageContract { } function setBytes32(bytes32 _value) public { + require(_value != bytes32(0), "Invalid bytes32 value"); bytes32Slot.tstore(_value); } @@ -36,6 +40,7 @@ contract StorageContract { } function setUint256(uint256 _value) public { + require(_value <= type(uint256).max, "Invalid uint256 value"); uint256Slot.tstore(_value); } @@ -44,6 +49,8 @@ contract StorageContract { } function setInt256(int256 _value) public { + require(_value >= type(int256).min, "Invalid int256 value"); + require(_value < type(int256).max, "Invalid int256 value"); int256Slot.tstore(_value); } @@ -52,26 +59,34 @@ contract StorageContract { } function storeIntTest(int256 _value) public returns (int256) { + require(_value >= type(int256).min, "Invalid int256 value"); + require(_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, "Input must be a boolean value"); + require(_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