Skip to content

Commit

Permalink
Merge pull request #252 from euler-xyz/test-stealth-donation
Browse files Browse the repository at this point in the history
LEND-184/Test stealth donation
  • Loading branch information
hoytech authored Aug 12, 2024
2 parents 1dad88b + 5623df9 commit 8db402e
Showing 1 changed file with 63 additions and 2 deletions.
65 changes: 63 additions & 2 deletions test/unit/evault/modules/Vault/deposit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {IEVC} from "ethereum-vault-connector/interfaces/IEthereumVaultConnector.

import "../../../../../src/EVault/shared/types/Types.sol";

import "forge-std/Test.sol";

contract VaultTest_Deposit is EVaultTestBase {
using TypesLib for uint256;

Expand All @@ -32,11 +34,11 @@ contract VaultTest_Deposit is EVaultTestBase {
user = vm.addr(userPK);
user1 = makeAddr("user1");

assetTST.mint(user1, type(uint256).max);
assetTST.mint(user1, type(uint256).max / 4);
hoax(user1);
assetTST.approve(address(eTST), type(uint256).max);

assetTST.mint(user, type(uint256).max);
assetTST.mint(user, type(uint256).max / 4);
startHoax(user);
assetTST.approve(address(eTST), type(uint256).max);
}
Expand Down Expand Up @@ -368,4 +370,63 @@ contract VaultTest_Deposit is EVaultTestBase {
assertEq(eTST.totalSupply(), 2 * amount);
assertEq(eTST.totalAssets(), 2 * amount);
}

function test_deposit_stealthDonation() public {
startHoax(address(this));
oracle.setPrice(address(assetTST), unitOfAccount, 1e18);
oracle.setPrice(address(assetTST2), unitOfAccount, 1e18);
eTST.setLTV(address(eTST2), 0.9e4, 0.9e4, 0);

startHoax(user1);
assetTST.mint(user1, 10e18);
assetTST.approve(address(eTST), type(uint256).max);
assetTST2.mint(user1, 100e18);
assetTST2.approve(address(eTST2), type(uint256).max);
eTST2.deposit(10e18, user1);
evc.enableController(user1, address(eTST));
evc.enableCollateral(user1, address(eTST2));

// attacker deposits 1 wei from one account
startHoax(user);
eTST.deposit(1, user);

// borrows it from a second for 1 second
startHoax(user1);
eTST.borrow(1, user1);
skip(1);

// 1 wei of debt accrued
assertEq(eTST.debtOf(user1), 2);
eTST.repay(type(uint256).max, user1);
eTST.disableController();

// and exchange rate is pushed above 1
assertEq(1.000000999999e18, eTST.convertToAssets(1e18)); // ~= 1.000001

assertEq(eTST.totalAssets(), 2); // 1 deposited + 1 interest repaid
assertEq(eTST.cash(), 2);
assertEq(eTST.totalSupply(), 1); // 1 deposited initially

// in a loop deposit max assets to create 1 share but not enough for 2. The rounding remainder is a stealth
// donation
for (uint256 i; i < 1000; i++) {
eTST.deposit(2, user1);
// 2 were deposited, but they round down to 1 share
assertEq(eTST.balanceOf(user1), 1);
// which is redeemable for 1 asset, the rest is donated
assertEq(eTST.maxWithdraw(user1), 1);

// reset account
eTST.withdraw(1, user1, user1);
assertEq(eTST.balanceOf(user1), 0);
}

// after 1000 iterations, 1000 assets were stealth donated
assertEq(eTST.totalAssets(), 1002);
assertEq(eTST.cash(), 1002);
assertEq(eTST.totalSupply(), 1);

// it will take 1e6 loops to reach exchange rate of 2
assertEq(1.001000998999001e18, eTST.convertToAssets(1e18)); // ~= 1.001
}
}

0 comments on commit 8db402e

Please sign in to comment.