Skip to content

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
6boris committed Oct 10, 2023
1 parent 3b35ec8 commit 9de5c52
Show file tree
Hide file tree
Showing 40 changed files with 1,955 additions and 16 deletions.
22 changes: 14 additions & 8 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
[submodule "foundry/lib/openzeppelin-contracts-v4"]
path = foundry/lib/openzeppelin-contracts-v4
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/prb-test"]
path = lib/prb-test
url = https://github.com/PaulRBerg/prb-test
[submodule "foundry/lib/openzeppelin-contracts"]
path = foundry/lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
Expand Down Expand Up @@ -40,3 +34,15 @@
[submodule "foundry/lib/solady"]
path = foundry/lib/solady
url = https://github.com/vectorized/solady
[submodule "foundry/lib/safe-contracts"]
path = foundry/lib/safe-contracts
url = https://github.com/safe-global/safe-contracts
[submodule "foundry/lib/openzeppelin-contracts-upgradeable"]
path = foundry/lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "foundry/lib/openzeppelin-contracts-upgradeable-v4.7.1"]
path = foundry/lib/openzeppelin-contracts-upgradeable-v4.7.1
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "foundry/lib/openzeppelin-contracts-v4.7.1"]
path = foundry/lib/openzeppelin-contracts-v4.7.1
url = https://github.com/OpenZeppelin/openzeppelin-contracts
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ git submodule update --init --recursive

# OR
forge install foundry-rs/[email protected] --no-commit
forge install OpenZeppelin/[email protected] --no-commit

forge install transmissions11/solmate@0384dbaaa4fcb5715738a9254a7c0a4cb62cf458 --no-commit
forge install vectorized/[email protected] --no-commit

Expand All @@ -27,6 +27,24 @@ forge install Uniswap/v3-core --no-commit
forge install Uniswap/v4-periphery --no-commit
forge install Uniswap/v4-core --no-commit

forge install OpenZeppelin/[email protected] --no-commit
forge install OpenZeppelin/[email protected] --no-commit

# OpenZeppelin v4
v4.7.1

git clone https://github.com/OpenZeppelin/openzeppelin-contracts foundry/lib/openzeppelin-contracts-v4.7.1 && cd foundry/lib/openzeppelin-contracts-v4.7.1 && git checkout tags/v4.7.1

git clone https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable foundry/lib/openzeppelin-contracts-upgradeable-v4.7.1 && cd foundry/lib/openzeppelin-contracts-upgradeable-v4.7.1 && git checkout tags/v4.7.1

git rm --cached foundry/lib/openzeppelin-contracts-v4.7.1

git submodule add https://github.com/OpenZeppelin/openzeppelin-contracts foundry/lib/openzeppelin-contracts-v4.7.1

git submodule add https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable foundry/lib/openzeppelin-contracts-upgradeable-v4.7.1

forge install safe-global/[email protected] --no-commit

```

```bash
Expand Down
27 changes: 27 additions & 0 deletions contracts/CTF/Damn-Vulnerable-DeFi/00.Base/DamnValuableNFT.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts-v4.7.1/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts-v4.7.1/token/ERC721/extensions/ERC721Burnable.sol";
import "@solady/auth/OwnableRoles.sol";

/**
* @title DamnValuableNFT
* @author Damn Vulnerable DeFi (https://damnvulnerabledefi.xyz)
* @notice Implementation of a mintable and burnable NFT with role-based access controls
*/
contract DamnValuableNFT is ERC721, ERC721Burnable, OwnableRoles {
uint256 public constant MINTER_ROLE = _ROLE_0;
uint256 public tokenIdCounter;

constructor() ERC721("DamnValuableNFT", "DVNFT") {
_initializeOwner(msg.sender);
_grantRoles(msg.sender, MINTER_ROLE);
}

function safeMint(address to) public onlyRoles(MINTER_ROLE) returns (uint256 tokenId) {
tokenId = tokenIdCounter;
_safeMint(to, tokenId);
++tokenIdCounter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-v4.7.1/token/ERC20/extensions/ERC20Snapshot.sol";

/**
* @title DamnValuableTokenSnapshot
* @author Damn Vulnerable DeFi (https://damnvulnerabledefi.xyz)
*/
contract DamnValuableTokenSnapshot is ERC20Snapshot {
uint256 private _lastSnapshotId;

constructor(uint256 initialSupply) ERC20("DamnValuableToken", "DVT") {
_mint(msg.sender, initialSupply);
}

// @audit-issue no access control, anyone can take a snapshot
function snapshot() public returns (uint256 lastSnapshotId) {
lastSnapshotId = _snapshot();
_lastSnapshotId = lastSnapshotId;
}

function getBalanceAtLastSnapshot(address account) external view returns (uint256) {
return balanceOfAt(account, _lastSnapshotId);
}

function getTotalSupplyAtLastSnapshot() external view returns (uint256) {
return totalSupplyAt(_lastSnapshotId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity ^0.8.0;

import "@solmate/auth/Owned.sol";
import "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol";
import "@openzeppelin/contracts-v4.7.1/interfaces/IERC3156FlashBorrower.sol";
import { UnstoppableVault, ERC20 } from "./UnstoppableVault.sol";

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Owned } from "@solmate/auth/Owned.sol";
import { FixedPointMathLib } from "@solmate/utils/FixedPointMathLib.sol";
import { ReentrancyGuard } from "@solmate/utils/ReentrancyGuard.sol";
import { SafeTransferLib, ERC4626, ERC20 } from "@solmate/mixins/ERC4626.sol";
import { IERC3156FlashBorrower, IERC3156FlashLender } from "@openzeppelin/contracts/interfaces/IERC3156.sol";
import { IERC3156FlashBorrower, IERC3156FlashLender } from "@openzeppelin/contracts-v4.7.1/interfaces/IERC3156.sol";

/**
* @title UnstoppableVault
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

pragma solidity ^0.8.0;

import { SafeTransferLib } from "solady/src/utils/SafeTransferLib.sol";
import { IERC3156FlashBorrower } from "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol";
import { SafeTransferLib } from "@solady/utils/SafeTransferLib.sol";
import { IERC3156FlashBorrower } from "@openzeppelin/contracts-v4.7.1/interfaces/IERC3156FlashBorrower.sol";
import { NaiveReceiverLenderPool } from "./NaiveReceiverLenderPool.sol";

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import { IERC3156FlashBorrower, IERC3156FlashLender } from "@openzeppelin/contracts/interfaces/IERC3156.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts-v4.7.1/security/ReentrancyGuard.sol";
import { IERC3156FlashBorrower, IERC3156FlashLender } from "@openzeppelin/contracts-v4.7.1/interfaces/IERC3156.sol";
import { SafeTransferLib } from "@solady/utils/SafeTransferLib.sol";
import { FlashLoanReceiver } from "./FlashLoanReceiver.sol";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-v4.7.1/utils/Address.sol";
import "@openzeppelin/contracts-v4.7.1/security/ReentrancyGuard.sol";
import { DamnValuableToken } from "@contracts/CTF/Damn-Vulnerable-DeFi/00.Base/DamnValuableToken.sol";

/**
* @title TrusterLenderPool
* @author Damn Vulnerable DeFi (https://damnvulnerabledefi.xyz)
*/
contract TrusterLenderPool is ReentrancyGuard {
using Address for address;

DamnValuableToken public immutable token;

error RepayFailed();

constructor(DamnValuableToken _token) {
token = _token;
}

function flashLoan(
uint256 amount,
address borrower,
address target,
bytes calldata data
)
external
nonReentrant
returns (bool)
{
uint256 balanceBefore = token.balanceOf(address(this));

token.transfer(borrower, amount);

// @audit-issue Execute abitraty call to any contract on behald of the pool
target.functionCall(data);

if (token.balanceOf(address(this)) < balanceBefore) {
revert RepayFailed();
}

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@solady/utils/SafeTransferLib.sol";

interface IFlashLoanEtherReceiver {
function execute() external payable;
}

/**
* @title SideEntranceLenderPool
* @author Damn Vulnerable DeFi (https://damnvulnerabledefi.xyz)
*/
contract SideEntranceLenderPool {
mapping(address => uint256) private balances;

error RepayFailed();

event Deposit(address indexed who, uint256 amount);
event Withdraw(address indexed who, uint256 amount);

function deposit() external payable {
unchecked {
balances[msg.sender] += msg.value;
}
emit Deposit(msg.sender, msg.value);
}

function withdraw() external {
uint256 amount = balances[msg.sender];

delete balances[msg.sender];
emit Withdraw(msg.sender, amount);

SafeTransferLib.safeTransferETH(msg.sender, amount);
}

function flashLoan(uint256 amount) external {
uint256 balanceBefore = address(this).balance;

IFlashLoanEtherReceiver(msg.sender).execute{ value: amount }();

if (address(this).balance < balanceBefore) {
revert RepayFailed();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-v4.7.1/token/ERC20/extensions/ERC20Snapshot.sol";
import "@solady/auth/OwnableRoles.sol";

/**
* @title AccountingToken
* @author Damn Vulnerable DeFi (https://damnvulnerabledefi.xyz)
* @notice A limited pseudo-ERC20 token to keep track of deposits and withdrawals
* with snapshotting capabilities.
*/
contract AccountingToken is ERC20Snapshot, OwnableRoles {
uint256 public constant MINTER_ROLE = _ROLE_0;
uint256 public constant SNAPSHOT_ROLE = _ROLE_1;
uint256 public constant BURNER_ROLE = _ROLE_2;

error NotImplemented();

constructor() ERC20("rToken", "rTKN") {
_initializeOwner(msg.sender);
_grantRoles(msg.sender, MINTER_ROLE | SNAPSHOT_ROLE | BURNER_ROLE);
}

function mint(address to, uint256 amount) external onlyRoles(MINTER_ROLE) {
_mint(to, amount);
}

function burn(address from, uint256 amount) external onlyRoles(BURNER_ROLE) {
_burn(from, amount);
}

function snapshot() external onlyRoles(SNAPSHOT_ROLE) returns (uint256) {
return _snapshot();
}

function _transfer(address, address, uint256) internal pure override {
revert NotImplemented();
}

function _approve(address, address, uint256) internal pure override {
revert NotImplemented();
}
}

/**
* @title RewardToken
* @author Damn Vulnerable DeFi (https://damnvulnerabledefi.xyz)
*/
contract RewardToken is ERC20, OwnableRoles {
uint256 public constant MINTER_ROLE = _ROLE_0;

constructor() ERC20("Reward Token", "RWT") {
_initializeOwner(msg.sender);
_grantRoles(msg.sender, MINTER_ROLE);
}

function mint(address to, uint256 amount) external onlyRoles(MINTER_ROLE) {
_mint(to, amount);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-v4.7.1/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts-v4.7.1/utils/Address.sol";
import "../00.Base/DamnValuableToken.sol";

/**
* @title FlashLoanerPool
* @author Damn Vulnerable DeFi (https://damnvulnerabledefi.xyz)
* @dev A simple pool to get flashloans of DVT
*/
contract FlashLoanerPool is ReentrancyGuard {
using Address for address;

DamnValuableToken public immutable liquidityToken;

error NotEnoughTokenBalance();
error CallerIsNotContract();
error FlashLoanNotPaidBack();

constructor(address liquidityTokenAddress) {
liquidityToken = DamnValuableToken(liquidityTokenAddress);
}

function flashLoan(uint256 amount) external nonReentrant {
uint256 balanceBefore = liquidityToken.balanceOf(address(this));

if (amount > balanceBefore) {
revert NotEnoughTokenBalance();
}

// @audit-issue can be bypassed if we call it from a constructor
if (!msg.sender.isContract()) {
revert CallerIsNotContract();
}

liquidityToken.transfer(msg.sender, amount);

msg.sender.functionCall(abi.encodeWithSignature("receiveFlashLoan(uint256)", amount));

if (liquidityToken.balanceOf(address(this)) < balanceBefore) {
revert FlashLoanNotPaidBack();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
Loading

0 comments on commit 9de5c52

Please sign in to comment.