Fix logic of both contract

This commit is contained in:
amaqkkg 2025-01-05 10:39:47 +07:00
parent cef1c434d4
commit 9c320eb62f
3 changed files with 50 additions and 30 deletions

View File

@ -3,13 +3,14 @@
pragma solidity 0.8.28;
import {IDRCoin} from "./IDRCoin.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
contract BankHub is UUPSUpgradeable {
contract BankHub {
// constants
uint32 public constant MIN_INTEREST_RATE = 5;
uint32 public constant MAX_INTEREST_RATE = 100;
uint32 public constant DENOMINATOR = 100;
uint256 public constant MIN_LOAN_AMOUNT = 10e18;
uint256 public constant MAX_LOAN_AMOUNT = 100e18;
// state variables
address public owner;
@ -47,12 +48,8 @@ contract BankHub is UUPSUpgradeable {
event Withdraw(address indexed user, address indexed bank, uint256 amount);
event Approved(address indexed bank);
constructor() {
_disableInitializers();
}
function initialize() public initializer {
owner = msg.sender;
constructor(address _owner) {
owner = _owner;
}
// user function
@ -95,9 +92,9 @@ contract BankHub is UUPSUpgradeable {
idrcoin.mint(msg.sender, interest);
// transfer amount
idrcoin.transferFrom(address(_fromBank), msg.sender, _amount);
idrcoin.transferFrom(_fromBank, msg.sender, _amount);
emit Withdraw(msg.sender, _fromBank, _amount);
emit Withdraw(msg.sender, _fromBank, _amount + interest);
}
// bank function
@ -110,6 +107,9 @@ contract BankHub is UUPSUpgradeable {
if (_amount < MIN_LOAN_AMOUNT) {
revert insufficientLoanAmount();
}
if (_amount > MAX_LOAN_AMOUNT) {
revert insufficientLoanAmount();
}
idrcoin.mint(_bank, _amount);
}
@ -126,6 +126,11 @@ contract BankHub is UUPSUpgradeable {
owner = _newOwner;
}
// set IDRCoin address
function setIDRCoin(address _idrcoin) public onlyOwner {
idrcoin = IDRCoin(_idrcoin);
}
// whitelist partner bank, set interest rate and approve unlimited IDRCoin transfer by this contract
function whiteList(address _bank) public onlyOwner {
whiteListed[_bank] = true;
@ -137,17 +142,13 @@ contract BankHub is UUPSUpgradeable {
// revoke whitelist from partner bank
// collect all IDRCoin from bank
// this is used to punish bank that misbehave
function revokeWhiteList(address _bank) public onlyOwner {
if (idrcoin.balanceOf(_bank) > 0) {
idrcoin.transferFrom(_bank, owner, idrcoin.balanceOf(_bank));
}
}
// Implementation of the required UUPSUpgradeable function
function _authorizeUpgrade(address newImplementation) internal override {
require(msg.sender == owner, "only owner can authorize upgrades");
}
// view function
function isWhiteListed(address _bank) public view returns (bool) {
return whiteListed[_bank];

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IUSDT} from "./interfaces/IUSDT.sol";
import {IBankHub} from "./interfaces/IBankHub.sol";
@ -18,11 +19,12 @@ contract IDRCoin is ERC20 {
// constant
// convertion rate from USDT to IDR
uint256 constant public CONVERSION_RATE = 16000;
uint256 public constant CONVERSION_RATE = 16000;
uint8 public constant DECIMALS = 18;
// enforce ppn 12% for ALL MINTING transaction involving IDRC token
uint256 constant public TAX = 12;
uint256 constant public DENOMINATOR = 100;
uint256 public constant TAX = 12;
uint256 public constant DENOMINATOR = 100;
modifier onlyAdmin() {
if (msg.sender != admin) {
@ -47,8 +49,16 @@ contract IDRCoin is ERC20 {
error BankCannotManualApprove();
// event
event IDRC_Transfer(address indexed from, address indexed to, uint256 value);
event IDRC_Approval(address indexed owner, address indexed spender, uint256 value);
event IDRC_Transfer(
address indexed from,
address indexed to,
uint256 value
);
event IDRC_Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event IDRC_Mint(address indexed to, uint256 value);
event IDRC_Burn(address indexed from, uint256 value);
@ -81,9 +91,12 @@ contract IDRCoin is ERC20 {
// external/public function
// anyone can buy IDRC with USDT with fixed conversion rate
function convertUSDtoIDR(uint256 amountInUSD) external {
usdt.transfer(address(this), amountInUSD);
uint256 amountInIDR = amountInUSD * CONVERSION_RATE * decimals();
_mint(msg.sender, amountInIDR);
usdt.transferFrom(msg.sender, address(this), amountInUSD);
// first we normalize the amount in usd by dividing it with its own decimals
// then we multiply it with the conversion rate and IDRC decimals
// result is the amount of IDRC to mint with the correct decimals
uint256 amountInIDR = (amountInUSD / 10 ** usdt.decimals()) *CONVERSION_RATE * 10 ** decimals();
mint_(msg.sender, amountInIDR);
emit IDRC_Mint(msg.sender, amountInIDR);
}
@ -93,8 +106,8 @@ contract IDRCoin is ERC20 {
address _spender,
uint256 _amount
) public override returns (bool) {
// we dont want the bank to manually approve
// because it can be exploited by the bank, they can set _amount to 0 and the BankHub
// we dont want the bank to manually approve
// because it can be exploited by the bank, they can set _amount to 0 and the BankHub
// cannot spend the loaned IDRC
if (IBankHub(bankHub).isWhiteListed(msg.sender)) {
revert BankCannotManualApprove();
@ -178,6 +191,10 @@ contract IDRCoin is ERC20 {
return balances[_addr];
}
function decimals() public pure override returns (uint8) {
return DECIMALS;
}
// setter/admin function
// set the bankHub address
function setBankHub(address _bankHub) external onlyAdmin {
@ -194,7 +211,7 @@ contract IDRCoin is ERC20 {
admin = admin;
}
// change taxCollector address
// change taxCollector address
function changeTaxCollector(address _taxCollector) external onlyAdmin {
taxCollector = _taxCollector;
}

View File

@ -2,11 +2,13 @@
pragma solidity 0.8.28;
interface IUSDT {
function decimals() external returns (uint);
function decimals() external returns (uint256);
function balanceOf(address who) external returns (uint);
function balanceOf(address who) external returns (uint256);
function transfer(address to, uint value) external;
function transfer(address to, uint256 value) external;
function approve(address spender, uint value) external;
function transferFrom(address from, address to, uint256 value) external;
function approve(address spender, uint256 value) external;
}