// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.15;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
import {WETH} from "../tokens/WETH.sol";
contract WETHTest is DSTestPlus {
WETH weth;
function setUp() public {
weth = new WETH();
}
function testFallbackDeposit() public {
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
SafeTransferLib.safeTransferETH(address(weth), 1 ether);
assertEq(weth.balanceOf(address(this)), 1 ether);
assertEq(weth.totalSupply(), 1 ether);
}
function testDeposit() public {
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
weth.deposit{value: 1 ether}();
assertEq(weth.balanceOf(address(this)), 1 ether);
assertEq(weth.totalSupply(), 1 ether);
}
function testWithdraw() public {
uint256 startingBalance = address(this).balance;
weth.deposit{value: 1 ether}();
weth.withdraw(1 ether);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, startingBalance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
}
function testPartialWithdraw() public {
weth.deposit{value: 1 ether}();
uint256 balanceBeforeWithdraw = address(this).balance;
weth.withdraw(0.5 ether);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + 0.5 ether);
assertEq(weth.balanceOf(address(this)), 0.5 ether);
assertEq(weth.totalSupply(), 0.5 ether);
}
function testFallbackDeposit(uint256 amount) public {
amount = bound(amount, 0, address(this).balance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
SafeTransferLib.safeTransferETH(address(weth), amount);
assertEq(weth.balanceOf(address(this)), amount);
assertEq(weth.totalSupply(), amount);
}
function testDeposit(uint256 amount) public {
amount = bound(amount, 0, address(this).balance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
weth.deposit{value: amount}();
assertEq(weth.balanceOf(address(this)), amount);
assertEq(weth.totalSupply(), amount);
}
function testWithdraw(uint256 depositAmount, uint256 withdrawAmount) public {
depositAmount = bound(depositAmount, 0, address(this).balance);
withdrawAmount = bound(withdrawAmount, 0, depositAmount);
weth.deposit{value: depositAmount}();
uint256 balanceBeforeWithdraw = address(this).balance;
weth.withdraw(withdrawAmount);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + withdrawAmount);
assertEq(weth.balanceOf(address(this)), depositAmount - withdrawAmount);
assertEq(weth.totalSupply(), depositAmount - withdrawAmount);
}
receive() external payable {}
}
contract WETHInvariants is DSTestPlus, DSInvariantTest {
WETHTester wethTester;
WETH weth;
function setUp() public {
weth = new WETH();
wethTester = new WETHTester{value: address(this).balance}(weth);
addTargetContract(address(wethTester));
}
function invariantTotalSupplyEqualsBalance() public {
assertEq(address(weth).balance, weth.totalSupply());
}
}
contract WETHTester {
WETH weth;
constructor(WETH _weth) payable {
weth = _weth;
}
function deposit(uint256 amount) public {
weth.deposit{value: amount}();
}
function fallbackDeposit(uint256 amount) public {
SafeTransferLib.safeTransferETH(address(weth), amount);
}
function withdraw(uint256 amount) public {
weth.withdraw(amount);
}
receive() external payable {}
}