// SPDX-License-Identifier: MIT pragma solidity 0.8.28; import "forge-std/Test.sol"; import {IDRCoin} from "../src/IDRCoin.sol"; import {BankHub} from "../src/BankHub.sol"; import {USDTMock} from "./ERC20Mock.sol"; contract Base is Test { IDRCoin public idrCoin; BankHub public bankHub; USDTMock public usdtMock; address admin = makeAddr("admin"); address taxCollector = makeAddr("taxCollector"); address bankABC = makeAddr("bankABC"); address bankIRB = makeAddr("bankIRB"); address alice = makeAddr("alice"); address bob = makeAddr("bob"); function setUp() public { vm.startPrank(admin); // deploy the contract idrCoin = new IDRCoin(admin, taxCollector); bankHub = new BankHub(admin); usdtMock = new USDTMock(); // set the bankHub address in idrCoin idrCoin.setBankHub(address(bankHub)); // set usdtMock address in idrCoin idrCoin.setUSDT(address(usdtMock)); // set the idrCoin address in bankHub bankHub.setIDRCoin(address(idrCoin)); // set bank ABC and bank IRB as whiteListed bankHub.whiteList(bankABC); bankHub.whiteList(bankIRB); // mint some USDT to alice and bob usdtMock.mint(alice, 1000e6); // usdtMock.mint(bob, 1000e6); vm.stopPrank(); } // helper function for converting USDT to IDRCoin function convertUSDTtoIDR(address user, uint256 amountInUSDT) public { vm.startPrank(user); if (usdtMock.balanceOf(user) < amountInUSDT) { usdtMock.mint(user, amountInUSDT); } usdtMock.approve(address(idrCoin), amountInUSDT); idrCoin.convertUSDtoIDR(amountInUSDT); console.log("user balance: ", idrCoin.balanceOf(user)); // check the balance is reduced by tax uint256 conversionRate = idrCoin.CONVERSION_RATE(); uint256 tax = idrCoin.TAX(); uint256 denominator = idrCoin.DENOMINATOR(); uint256 idrCoinDecimals = idrCoin.decimals(); uint256 usdtDecimals = usdtMock.decimals(); uint256 idrAmount = ((amountInUSDT * conversionRate) / 10 ** usdtDecimals) * 10 ** idrCoinDecimals; uint256 taxAmount = (idrAmount * tax) / denominator; uint256 balance = idrCoin.balanceOf(user); assertEq(balance, idrAmount - taxAmount); vm.stopPrank(); } function test_failIf_transferFromIDRCoinMoreThanOnce() public { // create charlie address address charlie = makeAddr("charlie"); // alice convert 100 dollar worth of usdt convertUSDTtoIDR(alice, 100e6); vm.startPrank(alice); uint256 spendingAllowance = idrCoin.balanceOf(alice) / 4; // alice approve bob to transfer her IDRCoin idrCoin.approve(bob, spendingAllowance); vm.stopPrank(); // bob transfer the IDRCoin from alice to charlie vm.startPrank(bob); idrCoin.transferFrom(alice, charlie, spendingAllowance); vm.stopPrank(); // assert assertEq(idrCoin.balanceOf(alice), spendingAllowance * 3); assertEq(idrCoin.balanceOf(bob), 0); assertEq(idrCoin.balanceOf(charlie), spendingAllowance); // bob try to transfer the IDRCoin again from alice to bob vm.startPrank(bob); idrCoin.transferFrom(alice, charlie, spendingAllowance); vm.stopPrank(); // assert assertEq(idrCoin.balanceOf(alice), spendingAllowance * 2); assertEq(idrCoin.balanceOf(bob), 0); assertEq(idrCoin.balanceOf(charlie), spendingAllowance * 2); } }