Skip to content

Commit

Permalink
feat: validating supplier key in mint and burn (#167)
Browse files Browse the repository at this point in the history
Signed-off-by: Mariusz Jasuwienas <[email protected]>
  • Loading branch information
arianejasuwienas committed Feb 6, 2025
1 parent 1df3fce commit 488c8e1
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 12 deletions.
1 change: 1 addition & 0 deletions contracts/HederaResponseCodes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pragma solidity ^0.8.0;

library HederaResponseCodes {
int32 internal constant SUCCESS = 22; // The transaction succeeded
int32 internal constant TOKEN_HAS_NO_SUPPLY_KEY = 180;
}
23 changes: 21 additions & 2 deletions contracts/HtsSystemContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ contract HtsSystemContract is IHederaTokenService {
assembly { accountId := sload(slot) }
}

function mintToken(address token, int64 amount, bytes[] memory) htsCall external returns (
function mintToken(address token, int64 amount, bytes[] memory data) htsCall external returns (
int64 responseCode,
int64 newTotalSupply,
int64[] memory serialNumbers
) {
return mintToken(token, amount, false);
}

function mintToken(address token, int64 amount, bool ignoreSupplyKeyCheck) htsCall internal returns (
int64 responseCode,
int64 newTotalSupply,
int64[] memory serialNumbers
Expand All @@ -67,6 +75,13 @@ contract HtsSystemContract is IHederaTokenService {
(int64 tokenInfoResponseCode, TokenInfo memory tokenInfo) = IHederaTokenService(token).getTokenInfo(token);
require(tokenInfoResponseCode == HederaResponseCodes.SUCCESS, "mintToken: failed to get token info");

if (!ignoreSupplyKeyCheck) {
address supplyAccount = ITokenKey(token).getKeyAddress(0x10); // 0x10 - supply key
if (supplyAccount == address(0) || msg.sender != supplyAccount) {
return (HederaResponseCodes.TOKEN_HAS_NO_SUPPLY_KEY, tokenInfo.totalSupply, new int64[](0));
}
}

address treasuryAccount = tokenInfo.token.treasury;
require(treasuryAccount != address(0), "mintToken: invalid account");

Expand All @@ -88,6 +103,10 @@ contract HtsSystemContract is IHederaTokenService {
(int64 tokenInfoResponseCode, TokenInfo memory tokenInfo) = IHederaTokenService(token).getTokenInfo(token);
require(tokenInfoResponseCode == HederaResponseCodes.SUCCESS, "burnToken: failed to get token info");

address supplyAccount = ITokenKey(token).getKeyAddress(0x10); // 0x10 - supply key
if (supplyAccount == address(0) || msg.sender != supplyAccount) {
return (HederaResponseCodes.TOKEN_HAS_NO_SUPPLY_KEY, tokenInfo.totalSupply);
}
address treasuryAccount = tokenInfo.token.treasury;
require(treasuryAccount != address(0), "burnToken: invalid account");

Expand Down Expand Up @@ -189,7 +208,7 @@ contract HtsSystemContract is IHederaTokenService {
deployHIP719Proxy(tokenAddress);

if (initialTotalSupply > 0) {
this.mintToken(tokenAddress, initialTotalSupply, new bytes[](0));
mintToken(tokenAddress, initialTotalSupply, true);
}

responseCode = HederaResponseCodes.SUCCESS;
Expand Down
22 changes: 12 additions & 10 deletions test/HTS.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ contract HTSTest is Test, TestSetup {
int64 initialTotalSupply = 10000000005000000;
uint256 initialTreasuryBalance = IERC20(token).balanceOf(treasury);
bytes[] memory metadata = new bytes[](0);

address supplier = 0x00000000000000000000000000000000001c1aEC;
vm.prank(supplier);
(int64 responseCode, int64 newTotalSupply, int64[] memory serialNumbers) = IHederaTokenService(HTS_ADDRESS).mintToken(token, amount, metadata);
assertEq(responseCode, HederaResponseCodes.SUCCESS);
assertEq(serialNumbers.length, 0);
Expand Down Expand Up @@ -235,8 +236,8 @@ contract HTSTest is Test, TestSetup {
abi.encode(IHederaTokenService.getTokenInfo.selector),
abi.encode(HederaResponseCodes.SUCCESS, tokenInfo)
);
vm.expectRevert(bytes("mintToken: invalid account"));
IHederaTokenService(HTS_ADDRESS).mintToken(token, amount, metadata);
(int64 code, , ) = IHederaTokenService(HTS_ADDRESS).mintToken(token, amount, metadata);
assertEq(code, HederaResponseCodes.TOKEN_HAS_NO_SUPPLY_KEY);
}

function test_mintToken_should_revert_with_invalid_token() external {
Expand All @@ -258,12 +259,13 @@ contract HTSTest is Test, TestSetup {
}

function test_burnToken_should_succeed_with_valid_input() external {
address token = MFCT;
address treasury = MFCT_TREASURY;
address token = USDC;
address treasury = USDC_TREASURY;
address supplier = 0x00000000000000000000000000000000001c1aEC;
int64 amount = 1000;
int64 initialTotalSupply = 5000;
int64 initialTotalSupply = int64(int256(IERC20(token).totalSupply()));
uint256 initialTreasuryBalance = IERC20(token).balanceOf(treasury);

vm.startPrank(supplier);
(int64 responseCodeMint, int64 newTotalSupplyAfterMint, int64[] memory serialNumbers) = IHederaTokenService(HTS_ADDRESS).mintToken(token, amount, new bytes[](0));
assertEq(responseCodeMint, HederaResponseCodes.SUCCESS);
assertEq(serialNumbers.length, 0);
Expand All @@ -274,7 +276,7 @@ contract HTSTest is Test, TestSetup {
assertEq(responseCodeBurn, HederaResponseCodes.SUCCESS);
assertEq(newTotalSupplyAfterBurn, initialTotalSupply);
assertEq(IERC20(token).balanceOf(treasury), uint64(initialTreasuryBalance));

vm.stopPrank();
(int64 responseCodeGet, IHederaTokenService.TokenInfo memory tokenInfo) = IHederaTokenService(HTS_ADDRESS).getTokenInfo(token);
assertEq(responseCodeGet, HederaResponseCodes.SUCCESS);

Expand Down Expand Up @@ -304,8 +306,8 @@ contract HTSTest is Test, TestSetup {
abi.encode(IHederaTokenService.getTokenInfo.selector),
abi.encode(HederaResponseCodes.SUCCESS, tokenInfo)
);
vm.expectRevert(bytes("burnToken: invalid account"));
IHederaTokenService(HTS_ADDRESS).burnToken(token, amount, serialNumbers);
(int64 code, ) = IHederaTokenService(HTS_ADDRESS).burnToken(token, amount, serialNumbers);
assertEq(code, HederaResponseCodes.TOKEN_HAS_NO_SUPPLY_KEY);
}

function test_burnToken_should_revert_with_invalid_token() external {
Expand Down

0 comments on commit 488c8e1

Please sign in to comment.