generated from EthSign/hardhat-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
197 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
// solhint-disable ordering | ||
pragma solidity ^0.8.20; | ||
|
||
import {Test, console} from "forge-std/Test.sol"; | ||
import {TTUFeeCollector} from "../contracts/core/TTUFeeCollector.sol"; | ||
import {MockERC20} from "../contracts/mock/MockERC20.sol"; | ||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; | ||
|
||
contract TTUFeeCollectorTest is Test { | ||
using SafeERC20 for IERC20; | ||
|
||
TTUFeeCollector public instance; | ||
IERC20 public mockErc20; | ||
|
||
event DefaultFeeSetBips(uint256 bips); | ||
event CustomFeeSetBips(address unlockerAddress, uint256 bips); | ||
event CustomFeeSetFixed(address unlockerAddress, uint256 fixedFee); | ||
|
||
error FeesTooHigh(); | ||
|
||
// Ownable | ||
error OwnableUnauthorizedAccount(address account); | ||
|
||
function setUp() public { | ||
instance = new TTUFeeCollector(); | ||
mockErc20 = IERC20(address(new MockERC20())); | ||
} | ||
|
||
function testFuzz_setDefaultFeeBips_success(uint256 bips) public { | ||
vm.assume(bips <= instance.MAX_FEE_BIPS()); | ||
vm.expectEmit(); | ||
emit DefaultFeeSetBips(bips); | ||
instance.setDefaultFeeBips(bips); | ||
} | ||
|
||
function testFuzz_setDefaultFeeBips_fail_notOwner( | ||
address notOwner, | ||
uint256 bips | ||
) public { | ||
vm.assume(bips <= instance.MAX_FEE_BIPS() && notOwner != address(this)); | ||
vm.prank(notOwner); | ||
vm.expectRevert( | ||
abi.encodeWithSelector( | ||
OwnableUnauthorizedAccount.selector, | ||
notOwner | ||
) | ||
); | ||
instance.setDefaultFeeBips(bips); | ||
} | ||
|
||
function testFuzz_setDefaultFeeBips_fail_feesTooHigh(uint256 bips) public { | ||
vm.assume(bips > instance.MAX_FEE_BIPS()); | ||
vm.expectRevert(abi.encodeWithSelector(FeesTooHigh.selector)); | ||
instance.setDefaultFeeBips(bips); | ||
} | ||
|
||
function testFuzz_setCustomFeeBips_success( | ||
address unlockerAddress, | ||
uint256 bips | ||
) public { | ||
vm.assume(bips <= instance.MAX_FEE_BIPS()); | ||
vm.expectEmit(); | ||
emit CustomFeeSetBips(unlockerAddress, bips); | ||
instance.setCustomFeeBips(unlockerAddress, bips); | ||
} | ||
|
||
function testFuzz_setCustomFeeBips_fail_notOwner( | ||
address notOwner, | ||
address unlockerAddress, | ||
uint256 bips | ||
) public { | ||
vm.assume(bips <= instance.MAX_FEE_BIPS() && notOwner != address(this)); | ||
vm.prank(notOwner); | ||
vm.expectRevert( | ||
abi.encodeWithSelector( | ||
OwnableUnauthorizedAccount.selector, | ||
notOwner | ||
) | ||
); | ||
instance.setCustomFeeBips(unlockerAddress, bips); | ||
} | ||
|
||
function testFuzz_setCustomFeeBips_fail_feesTooHigh( | ||
address unlockerAddress, | ||
uint256 bips | ||
) public { | ||
vm.assume(bips > instance.MAX_FEE_BIPS()); | ||
vm.expectRevert(abi.encodeWithSelector(FeesTooHigh.selector)); | ||
instance.setCustomFeeBips(unlockerAddress, bips); | ||
} | ||
|
||
function testFuzz_getFee( | ||
uint16 defaultFeeBips, | ||
address customFeeUnlockerAddress, | ||
uint256 customFeeFixed, | ||
uint16 customFeeBips, | ||
uint128 tokenTransferred | ||
) public { | ||
vm.assume( | ||
defaultFeeBips <= instance.MAX_FEE_BIPS() && | ||
customFeeBips <= instance.MAX_FEE_BIPS() | ||
); | ||
instance.setDefaultFeeBips(defaultFeeBips); | ||
instance.setCustomFeeBips(customFeeUnlockerAddress, customFeeBips); | ||
instance.setCustomFeeFixed(customFeeUnlockerAddress, customFeeFixed); | ||
uint256 fees = instance.getFee( | ||
customFeeUnlockerAddress, | ||
tokenTransferred | ||
); | ||
if (customFeeFixed > 0) { | ||
assertEq(fees, customFeeFixed); | ||
} else if (customFeeBips > 0) { | ||
if (customFeeBips == instance.MAX_FEE_BIPS()) { | ||
assertEq(fees, 0); | ||
} else { | ||
assertEq( | ||
fees, | ||
(uint256(tokenTransferred) * customFeeBips) / | ||
instance.BIPS_PRECISION() | ||
); | ||
} | ||
} else { | ||
assertEq( | ||
fees, | ||
(uint256(tokenTransferred) * defaultFeeBips) / | ||
instance.BIPS_PRECISION() | ||
); | ||
} | ||
} | ||
|
||
function testFuzz_withdrawFee_success(uint256 amount) public { | ||
MockERC20(address(mockErc20)).mint(address(this), amount); | ||
mockErc20.safeTransfer(address(instance), amount); | ||
uint256 balanceBefore = mockErc20.balanceOf(address(this)); | ||
instance.withdrawFee(IERC20(mockErc20), amount); | ||
assertEq(mockErc20.balanceOf(address(this)) - balanceBefore, amount); | ||
} | ||
|
||
function testFuzz_withdrawFee_fail_notOwner( | ||
address notOwner, | ||
uint256 amount | ||
) public { | ||
vm.assume(notOwner != address(this)); | ||
MockERC20(address(mockErc20)).mint(address(this), amount); | ||
mockErc20.safeTransfer(address(instance), amount); | ||
vm.prank(notOwner); | ||
vm.expectRevert( | ||
abi.encodeWithSelector( | ||
OwnableUnauthorizedAccount.selector, | ||
notOwner | ||
) | ||
); | ||
instance.withdrawFee(IERC20(mockErc20), amount); | ||
} | ||
|
||
function testFuzz_withdrawFee_fail_wrongToken( | ||
address notMockErc20, | ||
uint256 amount | ||
) public { | ||
vm.assume(notMockErc20 != address(mockErc20)); | ||
MockERC20(address(mockErc20)).mint(address(this), amount); | ||
mockErc20.safeTransfer(address(instance), amount); | ||
vm.expectRevert(); | ||
instance.withdrawFee(IERC20(notMockErc20), amount); | ||
} | ||
} |