on Staking.sol contract in #L53-58 there are unchecked transfer which ignores the return value by WETH.transfer(msg.sender, claimable[msg.sender])
the function on L#53 ignores the return value by WETH.transfer(msg.sender, claimable[msg.sender]) which leaves the function vulnerable because of unchecked transfer, this happens and would lead to reentrancy vulnerability if it's not reverting or return the value of false, if the function were cancelled/interrupted by malicious actor(s). The external calls from L#55 which goes unchecked could be exploited because the state variable are written after the call, this could make space for reentrancy vulnerabilities by exploiting in-between calls by executing functions based on L#14 and L#24 mapping. The workflow would be detailed by these steps;
WETH.transfer(msg.sender,claimable[msg.sender]) (src/Staking.sol#55)
(src/Staking.sol#56) defining the amount of claimable amount will be 0 after claiming, but does not update yet the balance, while it supposed to check L#55 first
balance = WETH.balanceOf(address(this)) (src/Staking.sol#57)
Staking.balance (src/Staking.sol#14) can be used in cross function reentrancies:
Staking.balance (src/Staking.sol#14)
Staking.claim() (src/Staking.sol#53-58)
Staking.update() (src/Staking.sol#61-76)
claimable[msg.sender] = 0 (src/Staking.sol#56)
Staking.claimable (src/Staking.sol#24) can be used in cross function reentrancies:
Staking.claim() (src/Staking.sol#53-58)
Staking.claimable (src/Staking.sol#24)
Staking.updateFor(address) (src/Staking.sol#80-94)
Draining remaining token value within the contract
Slither
use SafeERC20 to/or ensure the the transfer/transferFrom function are properly checked, before and after the function were called. For the claim() function ensure by adding specific _amount just as the _withdraw and deposit has.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.