2023-12-12 22:10:27 +00:00
|
|
|
// SPDX-License-Identifier: UNLICENSED
|
|
|
|
|
|
|
|
pragma solidity ^0.8.17;
|
|
|
|
|
|
|
|
import { Test } from "forge-std/Test.sol";
|
|
|
|
import { TestERC20Token } from "../contracts/mocks/TestERC20Token.sol";
|
|
|
|
import { TestERC721Token } from "../contracts/mocks/TestERC721Token.sol";
|
|
|
|
import { CommunityVault } from "../contracts/CommunityVault.sol";
|
|
|
|
import { CommunityOwnable } from "../contracts/CommunityOwnable.sol";
|
|
|
|
import { DeploymentConfig } from "../script/DeploymentConfig.s.sol";
|
|
|
|
import { DeployOwnerAndMasterToken } from "../script/DeployOwnerAndMasterToken.s.sol";
|
|
|
|
import { CommunityERC20 } from "../contracts/tokens/CommunityERC20.sol";
|
|
|
|
import { OwnerToken } from "../contracts/tokens/OwnerToken.sol";
|
|
|
|
import { MasterToken } from "../contracts/tokens/MasterToken.sol";
|
|
|
|
|
|
|
|
contract CommunityVaultTest is Test {
|
|
|
|
CommunityVault internal vault;
|
|
|
|
|
|
|
|
address[] internal accounts = new address[](2);
|
|
|
|
address internal deployer;
|
|
|
|
|
|
|
|
TestERC20Token internal erc20Token;
|
|
|
|
TestERC721Token internal erc721Token;
|
|
|
|
CommunityERC20 internal communityERC20Token;
|
|
|
|
OwnerToken internal ownerToken;
|
|
|
|
MasterToken internal masterToken;
|
|
|
|
|
|
|
|
function setUp() public virtual {
|
|
|
|
DeploymentConfig deploymentConfig;
|
|
|
|
DeployOwnerAndMasterToken deployment = new DeployOwnerAndMasterToken();
|
|
|
|
(ownerToken, masterToken, deploymentConfig) = deployment.run();
|
|
|
|
|
|
|
|
deployer = deploymentConfig.deployer();
|
|
|
|
|
|
|
|
erc20Token = new TestERC20Token();
|
|
|
|
erc721Token = new TestERC721Token();
|
|
|
|
|
|
|
|
communityERC20Token = new CommunityERC20("Test", "TST", 18, 100, "", address(ownerToken), address(masterToken));
|
|
|
|
|
|
|
|
vault = new CommunityVault(address(ownerToken), address(masterToken));
|
|
|
|
|
|
|
|
accounts[0] = makeAddr("one");
|
|
|
|
accounts[1] = makeAddr("two");
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_Deployment() public {
|
|
|
|
assertEq(vault.ownerToken(), address(ownerToken));
|
|
|
|
assertEq(vault.masterToken(), address(masterToken));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
contract CommunityVaultBaseERC20Test is CommunityVaultTest {
|
|
|
|
function setUp() public virtual override {
|
|
|
|
CommunityVaultTest.setUp();
|
2024-02-26 10:00:31 +00:00
|
|
|
erc20Token.mint(accounts[0], 10e18);
|
2023-12-12 22:10:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
contract TransferERC20ByNonAdminTest is CommunityVaultBaseERC20Test {
|
|
|
|
function setUp() public virtual override {
|
|
|
|
CommunityVaultBaseERC20Test.setUp();
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_revertIfCalledByNonAdmin() public {
|
|
|
|
uint256[] memory amounts = new uint256[](2);
|
|
|
|
amounts[0] = 1;
|
|
|
|
amounts[1] = 1;
|
|
|
|
|
|
|
|
vm.prank(accounts[0]);
|
|
|
|
|
|
|
|
vm.expectRevert(CommunityOwnable.CommunityOwnable_NotAuthorized.selector);
|
|
|
|
vault.transferERC20(address(erc20Token), accounts, amounts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
contract TransferERC20ByAdminTest is CommunityVaultBaseERC20Test {
|
2024-02-26 10:00:31 +00:00
|
|
|
uint256 depositAmount = 10e18;
|
|
|
|
|
2023-12-12 22:10:27 +00:00
|
|
|
function setUp() public virtual override {
|
|
|
|
CommunityVaultBaseERC20Test.setUp();
|
2024-02-26 10:00:31 +00:00
|
|
|
|
|
|
|
vm.startPrank(accounts[0]);
|
|
|
|
erc20Token.approve(address(vault), depositAmount);
|
|
|
|
vault.depositERC20(address(erc20Token), depositAmount);
|
|
|
|
vm.stopPrank();
|
2023-12-12 22:10:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function test_LengthMismatch() public {
|
|
|
|
uint256[] memory amounts = new uint256[](1);
|
|
|
|
amounts[0] = 5e18;
|
|
|
|
|
|
|
|
vm.prank(deployer);
|
|
|
|
vm.expectRevert(CommunityVault.CommunityVault_LengthMismatch.selector);
|
|
|
|
vault.transferERC20(address(erc20Token), accounts, amounts);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_TransferAmountZero() public {
|
|
|
|
uint256[] memory amounts = new uint256[](2);
|
|
|
|
amounts[0] = 5e18;
|
|
|
|
amounts[1] = 0;
|
|
|
|
|
|
|
|
vm.prank(deployer);
|
|
|
|
vm.expectRevert(CommunityVault.CommunityVault_TransferAmountZero.selector);
|
|
|
|
vault.transferERC20(address(erc20Token), accounts, amounts);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_NoRecipients() public {
|
|
|
|
uint256[] memory amounts = new uint256[](0);
|
|
|
|
address[] memory tmpAccounts = new address[](0);
|
|
|
|
|
|
|
|
vm.prank(deployer);
|
|
|
|
vm.expectRevert(CommunityVault.CommunityVault_NoRecipients.selector);
|
|
|
|
vault.transferERC20(address(erc20Token), tmpAccounts, amounts);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_AdminCanTransferERC20() public {
|
|
|
|
assertEq(erc20Token.balanceOf(address(vault)), 10e18);
|
2024-02-26 10:00:31 +00:00
|
|
|
assertEq(vault.erc20TokenBalances(address(erc20Token)), 10e18);
|
2023-12-12 22:10:27 +00:00
|
|
|
|
|
|
|
uint256[] memory amounts = new uint256[](2);
|
2024-02-26 10:00:31 +00:00
|
|
|
amounts[0] = 3e18;
|
|
|
|
amounts[1] = 3e18;
|
|
|
|
|
|
|
|
vm.prank(deployer);
|
|
|
|
vault.transferERC20(address(erc20Token), accounts, amounts);
|
|
|
|
|
|
|
|
assertEq(erc20Token.balanceOf(address(vault)), 4e18);
|
|
|
|
assertEq(vault.erc20TokenBalances(address(erc20Token)), 4e18);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_TransferERC20AmountTooBig() public {
|
|
|
|
assertEq(erc20Token.balanceOf(address(vault)), 10e18);
|
|
|
|
assertEq(vault.erc20TokenBalances(address(erc20Token)), 10e18);
|
|
|
|
|
|
|
|
uint256[] memory amounts = new uint256[](2);
|
|
|
|
amounts[0] = 10e18;
|
|
|
|
amounts[1] = 10e18;
|
2023-12-12 22:10:27 +00:00
|
|
|
|
|
|
|
vm.prank(deployer);
|
2024-02-26 10:00:31 +00:00
|
|
|
vm.expectRevert(CommunityVault.CommunityVault_ERC20TransferAmountTooBig.selector);
|
2023-12-12 22:10:27 +00:00
|
|
|
vault.transferERC20(address(erc20Token), accounts, amounts);
|
2024-02-26 10:00:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
contract DepositERC20Test is CommunityVaultBaseERC20Test {
|
|
|
|
function testSuccessfulDepositERC20() public {
|
|
|
|
uint256 depositAmount = 5;
|
|
|
|
uint256 initialVaultBalance = erc20Token.balanceOf(address(vault));
|
|
|
|
uint256 initialTokenBalanceValue = vault.erc20TokenBalances(address(erc20Token));
|
|
|
|
|
|
|
|
vm.startPrank(accounts[0]);
|
|
|
|
erc20Token.approve(address(vault), depositAmount);
|
|
|
|
vault.depositERC20(address(erc20Token), depositAmount);
|
|
|
|
vm.stopPrank();
|
2023-12-12 22:10:27 +00:00
|
|
|
|
2024-02-26 10:00:31 +00:00
|
|
|
assertEq(erc20Token.balanceOf(address(vault)), initialVaultBalance + depositAmount);
|
|
|
|
assertEq(vault.erc20TokenBalances(address(erc20Token)), initialTokenBalanceValue + depositAmount);
|
|
|
|
}
|
|
|
|
|
|
|
|
function testDepositZeroTokens() public {
|
|
|
|
vm.prank(accounts[0]);
|
|
|
|
vm.expectRevert(CommunityVault.CommunityVault_DepositAmountZero.selector);
|
|
|
|
vault.depositERC20(address(erc20Token), 0);
|
2023-12-12 22:10:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
contract CommunityVaultBaseERC721Test is CommunityVaultTest {
|
|
|
|
function setUp() public virtual override {
|
|
|
|
CommunityVaultTest.setUp();
|
|
|
|
|
2024-03-01 11:02:17 +00:00
|
|
|
// mint 4 token to user
|
2023-12-12 22:10:27 +00:00
|
|
|
address user = accounts[0];
|
|
|
|
erc721Token.mint(user);
|
|
|
|
erc721Token.mint(user);
|
2024-03-01 11:02:17 +00:00
|
|
|
erc721Token.mint(user);
|
|
|
|
erc721Token.mint(user);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
contract CommunityVaultBaseTransferERC721Test is CommunityVaultBaseERC721Test {
|
|
|
|
function setUp() public virtual override {
|
|
|
|
CommunityVaultBaseERC721Test.setUp();
|
|
|
|
|
|
|
|
address user = accounts[0];
|
2023-12-12 22:10:27 +00:00
|
|
|
|
|
|
|
// user transfer 2 tokens to the vault
|
2024-03-01 11:02:17 +00:00
|
|
|
uint256[] memory ids = new uint256[](3);
|
|
|
|
ids[0] = 0;
|
|
|
|
ids[1] = 1;
|
|
|
|
ids[2] = 2;
|
|
|
|
|
2023-12-12 22:10:27 +00:00
|
|
|
vm.startPrank(user);
|
2024-03-01 11:02:17 +00:00
|
|
|
erc721Token.approve(address(vault), ids[0]);
|
|
|
|
erc721Token.approve(address(vault), ids[1]);
|
|
|
|
erc721Token.approve(address(vault), ids[2]);
|
|
|
|
vault.depositERC721(address(erc721Token), ids);
|
2023-12-12 22:10:27 +00:00
|
|
|
vm.stopPrank();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-01 11:02:17 +00:00
|
|
|
contract TransferERC721ByNonAdminTest is CommunityVaultBaseTransferERC721Test {
|
2023-12-12 22:10:27 +00:00
|
|
|
function setUp() public virtual override {
|
2024-03-01 11:02:17 +00:00
|
|
|
CommunityVaultBaseTransferERC721Test.setUp();
|
2023-12-12 22:10:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function test_RevertIfCalledByNonAdmin() public {
|
|
|
|
uint256[] memory ids = new uint256[](2);
|
|
|
|
ids[0] = 0;
|
|
|
|
ids[1] = 1;
|
|
|
|
|
|
|
|
vm.prank(accounts[0]);
|
|
|
|
vm.expectRevert(CommunityOwnable.CommunityOwnable_NotAuthorized.selector);
|
|
|
|
|
|
|
|
vault.transferERC721(address(erc721Token), accounts, ids);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-01 11:02:17 +00:00
|
|
|
contract TransferERC721ByAdminTest is CommunityVaultBaseTransferERC721Test {
|
2023-12-12 22:10:27 +00:00
|
|
|
function setUp() public virtual override {
|
2024-03-01 11:02:17 +00:00
|
|
|
CommunityVaultBaseTransferERC721Test.setUp();
|
2023-12-12 22:10:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function test_LengthMismatch() public {
|
|
|
|
uint256[] memory ids = new uint256[](1);
|
|
|
|
ids[0] = 0;
|
|
|
|
|
|
|
|
vm.prank(deployer);
|
|
|
|
vm.expectRevert(CommunityVault.CommunityVault_LengthMismatch.selector);
|
|
|
|
vault.transferERC721(address(erc721Token), accounts, ids);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_NoRecipients() public {
|
|
|
|
uint256[] memory ids = new uint256[](0);
|
|
|
|
address[] memory tmpAccounts = new address[](0);
|
|
|
|
|
|
|
|
vm.prank(deployer);
|
|
|
|
vm.expectRevert(CommunityVault.CommunityVault_NoRecipients.selector);
|
|
|
|
vault.transferERC721(address(erc721Token), tmpAccounts, ids);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_AdminCanTransferERC721() public {
|
2024-03-01 11:02:17 +00:00
|
|
|
assertEq(erc721Token.balanceOf(address(vault)), 3);
|
|
|
|
assertEq(vault.erc721TokenBalances(address(erc721Token)), 3);
|
|
|
|
|
|
|
|
// accounts[0] has 1 token with id 3
|
|
|
|
assertEq(erc721Token.balanceOf(accounts[0]), 1);
|
|
|
|
assertEq(erc721Token.balanceOf(accounts[1]), 0);
|
2023-12-12 22:10:27 +00:00
|
|
|
|
|
|
|
assertEq(erc721Token.ownerOf(0), address(vault));
|
|
|
|
assertEq(erc721Token.ownerOf(1), address(vault));
|
2024-03-01 11:02:17 +00:00
|
|
|
assertEq(erc721Token.ownerOf(2), address(vault));
|
2023-12-12 22:10:27 +00:00
|
|
|
|
|
|
|
uint256[] memory ids = new uint256[](2);
|
|
|
|
ids[0] = 0;
|
|
|
|
ids[1] = 1;
|
|
|
|
|
|
|
|
vm.prank(deployer);
|
|
|
|
vault.transferERC721(address(erc721Token), accounts, ids);
|
|
|
|
|
2024-03-01 11:02:17 +00:00
|
|
|
assertEq(erc721Token.balanceOf(address(vault)), 1);
|
|
|
|
assertEq(vault.erc721TokenBalances(address(erc721Token)), 1);
|
|
|
|
|
|
|
|
assertEq(erc721Token.balanceOf(accounts[0]), 2);
|
|
|
|
assertEq(erc721Token.balanceOf(accounts[1]), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_RevertOnTransferERC721IfNotDeposited() public {
|
|
|
|
// id 3 is not deposited
|
|
|
|
assertEq(erc721Token.ownerOf(3), address(accounts[0]));
|
|
|
|
|
|
|
|
uint256[] memory ids = new uint256[](1);
|
|
|
|
ids[0] = 3;
|
|
|
|
|
|
|
|
address[] memory accountsList = new address[](1);
|
|
|
|
accountsList[0] = accounts[0];
|
|
|
|
|
|
|
|
vm.prank(deployer);
|
|
|
|
vm.expectRevert(CommunityVault.CommunityVault_ERC721TokenNotDeposited.selector);
|
|
|
|
vault.transferERC721(address(erc721Token), accountsList, ids);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
contract CommunityVaultDepositERC721Test is CommunityVaultBaseERC721Test {
|
|
|
|
function setUp() public virtual override {
|
|
|
|
CommunityVaultBaseERC721Test.setUp();
|
|
|
|
}
|
|
|
|
|
|
|
|
function testSuccessfulDepositERC721() public {
|
|
|
|
uint256[] memory ids = new uint256[](2);
|
|
|
|
ids[0] = 0;
|
|
|
|
ids[1] = 1;
|
|
|
|
|
|
|
|
uint256 initialVaultBalance = erc721Token.balanceOf(address(vault));
|
|
|
|
uint256 initialTokenBalanceValue = vault.erc721TokenBalances(address(erc721Token));
|
|
|
|
|
|
|
|
vm.startPrank(accounts[0]);
|
|
|
|
erc721Token.approve(address(vault), ids[0]);
|
|
|
|
erc721Token.approve(address(vault), ids[1]);
|
|
|
|
vault.depositERC721(address(erc721Token), ids);
|
|
|
|
vm.stopPrank();
|
|
|
|
|
|
|
|
assertEq(erc721Token.balanceOf(address(vault)), initialVaultBalance + 2);
|
|
|
|
assertEq(vault.erc721TokenBalances(address(erc721Token)), initialTokenBalanceValue + 2);
|
2023-12-12 22:10:27 +00:00
|
|
|
}
|
|
|
|
}
|
2024-03-02 14:53:52 +00:00
|
|
|
|
|
|
|
contract CommunityVaulWithdrawUntrackedERC721Test is CommunityVaultBaseERC721Test {
|
|
|
|
function setUp() public virtual override {
|
|
|
|
CommunityVaultBaseERC721Test.setUp();
|
|
|
|
vm.startPrank(accounts[0]);
|
|
|
|
// trasfer to contract ids 0 and 1
|
|
|
|
erc721Token.transferFrom(accounts[0], address(vault), 0);
|
|
|
|
erc721Token.transferFrom(accounts[0], address(vault), 1);
|
|
|
|
|
|
|
|
// deposit id 2
|
|
|
|
uint256[] memory ids = new uint256[](1);
|
|
|
|
ids[0] = 2;
|
|
|
|
erc721Token.approve(address(vault), 2);
|
|
|
|
vault.depositERC721(address(erc721Token), ids);
|
|
|
|
vm.stopPrank();
|
|
|
|
}
|
|
|
|
|
|
|
|
function testRevertWithdrawalIfTokenIsTracked() public {
|
|
|
|
uint256[] memory ids = new uint256[](1);
|
|
|
|
ids[0] = 2;
|
|
|
|
|
|
|
|
assertEq(erc721Token.ownerOf(2), address(vault));
|
|
|
|
assertEq(vault.getERC721DepositedTokenByIndex(address(erc721Token), 0), 2);
|
|
|
|
|
|
|
|
vm.prank(deployer);
|
|
|
|
vm.expectRevert(CommunityVault.CommunityVault_CannotWithdrawTrackedERC721.selector);
|
|
|
|
vault.withdrawUntrackedERC721(address(erc721Token), ids, accounts[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
function testSuccessfulDepositERC721() public {
|
|
|
|
uint256[] memory ids = new uint256[](2);
|
|
|
|
ids[0] = 0;
|
|
|
|
ids[1] = 1;
|
|
|
|
|
|
|
|
assertEq(erc721Token.ownerOf(0), address(vault));
|
|
|
|
assertEq(erc721Token.ownerOf(1), address(vault));
|
|
|
|
|
|
|
|
vm.prank(deployer);
|
|
|
|
vault.withdrawUntrackedERC721(address(erc721Token), ids, accounts[0]);
|
|
|
|
|
|
|
|
assertEq(erc721Token.ownerOf(0), accounts[0]);
|
|
|
|
assertEq(erc721Token.ownerOf(1), accounts[0]);
|
|
|
|
}
|
|
|
|
}
|