• LISA
    LISA
    • Public Scans
    • My Scans
    1. Scan
    2. ...
    2025-07-02 06:37:20
    Public
    Full Disclosure

    OWASP SC08-10 Contracts Audit

    high7
    Created By:
    Credit Usage:

    Predictable answer allows attackers to always guess correctly and drain funds.

    HIGH

    Description

    The guess function generates an "answer" using block.timestamp, block.difficulty, and msg.sender, which are predictable within the same transaction. An attacker can compute the answer in real-time and call guess with the correct value, allowing them to repeatedly drain 1 ether per successful call. This breaks the intended game logic and leads to loss of funds.

    Recommendation

    Use a secure random number generator such as Chainlink VRF, or implement a commit-reveal scheme to prevent on-chain predictability. Avoid relying solely on block variables for randomness.

    Affected Lines

    Line 8 – 12

    Integer overflow/underflow in balance` variable due to unchecked arithmetic operations

    HIGH

    Description

    The balance variable is of type uint8 (range 0-255). The increment and decrement functions perform unchecked arithmetic operations. When balance is 255, calling increment with any positive value will cause an overflow (e.g., 255 + 1 = 0). Similarly, decrementing when balance is 0 will underflow (e.g., 0 - 1 = 255). This leads to incorrect state updates and violates the expected accounting logic.

    Recommendation

    Use SafeMath for uint8 operations or upgrade to Solidity ^0.8.0+ which has built-in overflow checks. Add explicit checks (e.g., require(balance + value <= type(uint8).max, "Overflow") in increment and require(value <= balance, "Underflow") in decrement).

    Affected Lines

    Line 11 – 17

    Reentrancy vulnerability allows attackers to manipulate the contract state and potentially drain funds.

    HIGH

    Description

    The claimThrone function makes an external call to the previous king before updating the contract's state. This allows a malicious king contract to reenter the function, leading to inconsistent state updates and potential fund loss. Attackers can exploit this to bypass payment checks, drain contract funds, or manipulate the king and balance variables incorrectly.

    Recommendation

    Follow the checks-effects-interactions pattern. Update the balance and king state variables before making the external call. Save the previous king and balance in local variables, update the state, then send Ether to the previous king.

    Affected Lines

    Line 11 – 15

    Failed Ether transfer to the current king can permanently lock the contract.

    HIGH

    Description

    If the current king is a contract that cannot receive Ether (e.g., lacks a payable fallback function), the transfer in claimThrone will fail, reverting the transaction. This prevents any new user from becoming the king, effectively locking the contract. An attacker can exploit this by setting a malicious king contract to cause a denial-of-service.

    Recommendation

    Use a withdrawal pattern where the previous king must withdraw their balance manually. Alternatively, remove the require(sent, ...) statement, but this may allow kings to not receive their dues. Ensure the king address can handle Ether transfers before allowing it to become king.

    Affected Lines

    Line 11 – 12

    Predictable answer allows attackers to drain contract funds

    HIGH

    Description

    The guess function generates an "answer" using block.timestamp, block.difficulty, and msg.sender, which are predictable/controllable by miners or attackers. An attacker can compute the answer in advance by submitting a transaction that executes in the same block, allowing them to always win and drain the contract's ETH. This makes the game trivially exploitable.

    Recommendation

    Use a commit-reveal scheme with a secure randomness source (e.g., Chainlink VRF) that cannot be predicted by attackers. Avoid relying solely on on-chain data like block variables for critical randomness.

    Affected Lines

    Line 8 – 12

    Integer overflow/underflow in balance updates

    HIGH

    Description

    The contract uses uint8 for balance, which can hold values from 0 to 255. The increment and decrement functions do not check for overflows/underflows. In Solidity <0.8.0, arithmetic operations wrap around on overflow. For example, if balance is 255 and increment(1) is called, it will wrap to 0 instead of reverting. Similarly, decrementing 0 by 1 will underflow to 255. This leads to incorrect accounting of the balance, which is a high-risk vulnerability as it fundamentally breaks the contract's state logic.

    Recommendation

    Upgrade to Solidity ≥0.8.0 which has built-in overflow checks, or implement explicit checks using SafeMath for uint8. For example:

    // Before 0.8.0, using SafeMath
    require(balance + value <= 255, "Overflow");
    balance += value;
    

    Affected Lines

    • SC08-int.sol: Line 11 – 17
    • SC08-int.sol: Line 12 – 12

    Reentrancy vulnerability allows attackers to drain contract funds

    HIGH

    Description

    The contract sends Ether to the previous king before updating the state variables (balance and king). An attacker can become the king and then, in the fallback function of the receiving contract, re-enter the claimThrone function. Since the state hasn't been updated yet, the attacker can repeatedly claim the throne, causing the contract to send out the old balance multiple times, potentially draining the contract's funds.

    Recommendation

    Update the state variables (balance and king) before making the external call. This follows the checks-effects-interactions pattern to prevent reentrancy attacks.

    Affected Lines

    Line 11 – 15