ghost-dao-contracts/test/tokens/Reserve.t.sol
Uncle Fatso 9e40d4ed4f
tests of the burning functionality
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
2025-06-27 21:39:38 +03:00

274 lines
9.2 KiB
Solidity

pragma solidity 0.8.20;
import {Test} from "forge-std/Test.sol";
import "../../src/mocks/Reserve.sol";
import "@openzeppelin-contracts/token/ERC20/IERC20.sol";
contract ReserveTest is Test {
address constant initializer = 0x0000000000000000000000000000000000000001;
address constant faucetAddress = 0x0000000000000000000000000000000000000002;
address constant aliceAddress = 0x0000000000000000000000000000000000000003;
address constant bobAddress = 0x0000000000000000000000000000000000000004;
uint256 constant conversionRate = 69 * 10e5;
uint256 constant sendAmount = 1e16;
string constant name = "Test DAI";
string constant symbol = "tDAI";
Reserve reserve;
event Transfer(address indexed from, address indexed to, uint256 value);
event LogStakingContractUpdated(address stakingContract);
function setUp() public {
vm.prank(initializer);
reserve = new Reserve(
"Test DAI",
"tDAI",
conversionRate
);
}
function test_isConstructedCorrectly() public view {
assertEq(reserve.name(), name);
assertEq(reserve.symbol(), symbol);
assertEq(reserve.decimals(), 18);
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.donationRate(), 0);
assertEq(reserve.conversionRate(), conversionRate);
}
function test_mint_couldBeDoneWithValue() public {
assertEq(reserve.balanceOf(aliceAddress), 0);
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
assertEq(reserve.balanceOf(aliceAddress), sendAmount * conversionRate);
}
function test_mint_couldNotBeDoneWithoutEmptyValue() public {
assertEq(reserve.balanceOf(aliceAddress), 0);
vm.prank(aliceAddress);
reserve.mint(aliceAddress);
assertEq(reserve.balanceOf(aliceAddress), 0);
}
function test_mint_couldNotMintIfNotEnoughValue() public {
assertEq(reserve.balanceOf(aliceAddress), 0);
bool didRevert = false;
vm.prank(aliceAddress);
try reserve.mint{ value: type(uint256).max }(aliceAddress) {
} catch {
didRevert = true;
}
assertEq(didRevert, true);
assertEq(reserve.balanceOf(aliceAddress), 0);
}
function test_mint_superMintCouldBeDoneFromDeployer() public {
assertEq(reserve.balanceOf(initializer), 0);
vm.prank(initializer);
reserve.superMint(initializer, 420 * 1e18);
assertEq(reserve.balanceOf(initializer), 420 * 1e18);
}
function test_mint_superMintCouldNotBeDoneFromArbitraryAddress() public {
assertEq(reserve.balanceOf(aliceAddress), 0);
vm.expectRevert();
vm.prank(aliceAddress);
reserve.superMint(aliceAddress, 420 * 1e18);
assertEq(reserve.balanceOf(aliceAddress), 0);
}
function test_mint_donationNotTakenIfRateNotSet() public {
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.donationRate(), 0);
assertEq(reserve.accumulatedDonation(), 0);
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
assertEq(reserve.totalSupply(), sendAmount * conversionRate);
assertEq(reserve.donationRate(), 0);
assertEq(reserve.accumulatedDonation(), 0);
}
function test_mint_donationIsTakenIfRateExists() public {
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.donationRate(), 0);
assertEq(reserve.accumulatedDonation(), 0);
vm.prank(initializer);
reserve.changeDonationRate(1e4); // 10%
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
assertEq(reserve.totalSupply(), sendAmount * conversionRate);
assertEq(reserve.donationRate(), 1e4);
assertEq(reserve.accumulatedDonation(), sendAmount * 1e4 / 1e5);
}
function test_rate_couldBeChangedByDeployer() public {
assertEq(reserve.conversionRate(), conversionRate);
vm.prank(initializer);
reserve.changeRate(1337);
assertEq(reserve.conversionRate(), 1337);
}
function test_rate_couldNotBeChangedByArbitraryAddress() public {
assertEq(reserve.conversionRate(), conversionRate);
vm.expectRevert();
vm.prank(aliceAddress);
reserve.changeRate(1337);
assertEq(reserve.conversionRate(), conversionRate);
}
function test_withdraw_couldBeDoneByDeployer() public {
assertEq(address(reserve).balance, 0);
vm.prank(initializer);
reserve.changeDonationRate(1e5);
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
assertEq(address(reserve).balance, sendAmount);
vm.prank(initializer);
reserve.withdraw(payable(faucetAddress));
assertEq(address(reserve).balance, 0);
assertEq(faucetAddress.balance, sendAmount);
}
function test_withdraw_onlyAccumulatedDonationsCouldBeWithdrawn() public {
assertEq(address(reserve).balance, 0);
vm.prank(initializer);
reserve.changeDonationRate(5 * 1e4); // 50%
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
assertEq(address(reserve).balance, sendAmount);
vm.prank(initializer);
reserve.withdraw(payable(faucetAddress));
assertEq(address(reserve).balance, sendAmount / 2);
assertEq(faucetAddress.balance, sendAmount / 2);
vm.prank(initializer);
reserve.withdraw(payable(faucetAddress));
assertEq(address(reserve).balance, sendAmount / 2);
assertEq(faucetAddress.balance, sendAmount / 2);
}
function test_withdraw_couldNotBeDoneByArbitraryAddress() public {
assertEq(address(reserve).balance, 0);
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
assertEq(address(reserve).balance, sendAmount);
vm.expectRevert();
vm.prank(aliceAddress);
reserve.withdraw(payable(aliceAddress));
assertEq(address(reserve).balance, sendAmount);
assertEq(aliceAddress.balance, 0);
}
function test_burn_shouldReturnFullAmountIfRateNotSet() public {
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
uint256 balance = reserve.balanceOf(aliceAddress);
assertEq(reserve.totalSupply(), sendAmount * conversionRate);
assertEq(reserve.totalSupply(), balance);
assertEq(reserve.accumulatedDonation(), 0);
assertEq(aliceAddress.balance, 0);
vm.prank(aliceAddress);
reserve.burn(balance);
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.balanceOf(aliceAddress), 0);
assertEq(reserve.accumulatedDonation(), 0);
assertEq(aliceAddress.balance, sendAmount);
}
function test_burn_shouldTakeDonationInAccordanceToRate() public {
vm.prank(initializer);
reserve.changeDonationRate(5 * 1e4); // 50%
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
uint256 balance = reserve.balanceOf(aliceAddress);
assertEq(reserve.totalSupply(), sendAmount * conversionRate);
assertEq(reserve.totalSupply(), balance);
assertEq(reserve.accumulatedDonation(), sendAmount / 2);
assertEq(aliceAddress.balance, 0);
vm.prank(aliceAddress);
reserve.burn(balance);
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.balanceOf(aliceAddress), 0);
assertEq(reserve.accumulatedDonation(), sendAmount / 2);
assertEq(aliceAddress.balance, sendAmount / 2);
}
function test_burn_multipleUsersAccumulateInTotal() public {
vm.prank(initializer);
reserve.changeDonationRate(5 * 1e4); // 50%
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
vm.prank(initializer);
reserve.changeRate(conversionRate * 9);
deal(bobAddress, sendAmount);
vm.prank(bobAddress);
reserve.mint{ value: sendAmount }(bobAddress);
assertEq(aliceAddress.balance, 0);
assertEq(bobAddress.balance, 0);
uint256 aliceBalance = reserve.balanceOf(aliceAddress);
uint256 bobBalance = reserve.balanceOf(bobAddress);
uint256 bobEstimation = reserve.estimateAmount(bobBalance);
uint256 aliceEstimation = reserve.estimateAmount(aliceBalance);
vm.prank(bobAddress);
reserve.burn(bobBalance);
vm.prank(aliceAddress);
reserve.burn(aliceBalance);
assertEq(bobAddress.balance, sendAmount * 9 / 10);
assertEq(bobAddress.balance, bobEstimation);
assertEq(aliceAddress.balance, sendAmount / 10);
assertEq(aliceAddress.balance, aliceEstimation);
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.accumulatedDonation(), sendAmount);
assertEq(address(reserve).balance, sendAmount);
}
}