Skip to content

Commit

Permalink
feat: implementation of transferTokens method (#200) (#211)
Browse files Browse the repository at this point in the history
Signed-off-by: Mariusz Jasuwienas <[email protected]>
  • Loading branch information
arianejasuwienas authored Jan 22, 2025
1 parent b92137f commit fd99e8a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 5 deletions.
15 changes: 15 additions & 0 deletions contracts/HtsSystemContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,21 @@ contract HtsSystemContract is IHederaTokenService, IERC20Events, IERC721Events {
return dissociateTokens(account, tokens);
}

function transferTokens(
address token,
address[] memory accountId,
int64[] memory amount
) htsCall external returns (int64 responseCode) {
require(token != address(0), "transferTokens: invalid token");
require(accountId.length > 0, "transferTokens: missing recipients");
require(amount.length == accountId.length, "transferTokens: inconsistent input");
for (uint256 i = 0; i < accountId.length; i++) {
responseCode = transferToken(token, msg.sender, accountId[i], amount[i]);
require(responseCode == HederaResponseCodes.SUCCESS, "transferTokens: transfer failed");
}
responseCode = HederaResponseCodes.SUCCESS;
}

function transferNFTs(
address token,
address[] memory sender,
Expand Down
10 changes: 5 additions & 5 deletions contracts/IHederaTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -462,11 +462,11 @@ interface IHederaTokenService {
/// @param token The ID of the token as a solidity address
/// @param accountId account to do a transfer to/from
/// @param amount The amount from the accountId at the same index
// function transferTokens(
// address token,
// address[] memory accountId,
// int64[] memory amount
// ) external returns (int64 responseCode);
function transferTokens(
address token,
address[] memory accountId,
int64[] memory amount
) external returns (int64 responseCode);

/// Initiates a Non-Fungable Token Transfer
/// @param token The ID of the token as a solidity address
Expand Down
58 changes: 58 additions & 0 deletions test/HTS.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,64 @@ contract HTSTest is Test, TestSetup {
assertEq(IERC721(CFNFTFF).ownerOf(serialId), to);
}

function test_HTS_transferTokens_success() public {
// https://hashscan.io/testnet/account/0.0.1421
address owner = 0x4D1c823b5f15bE83FDf5adAF137c2a9e0E78fE15;
address[] memory to = new address[](1);
to[0] = makeAddr("bob");
uint256 amount = 4_000000;
int64[] memory amounts = new int64[](1);
amounts[0] = int64(int256(amount));

uint256 balanceOfOwner = IERC20(USDC).balanceOf(owner);
assertGt(balanceOfOwner, 0);
assertEq(IERC20(USDC).balanceOf(to[0]), 0);

vm.prank(owner);
vm.expectEmit(USDC);
emit IERC20Events.Transfer(owner, to[0], amount);
IHederaTokenService(HTS_ADDRESS).transferTokens(USDC, to, amounts);

assertEq(IERC20(USDC).balanceOf(owner), balanceOfOwner - amount);
assertEq(IERC20(USDC).balanceOf(to[0]), amount);
}

function test_HTS_transferTokens_invalid_token_address() public {
// https://hashscan.io/testnet/account/0.0.1421
address owner = 0x4D1c823b5f15bE83FDf5adAF137c2a9e0E78fE15;
address[] memory to = new address[](1);
to[0] = makeAddr("bob");
int64[] memory amounts = new int64[](1);
amounts[0] = 4_000000;
vm.prank(owner);
vm.expectRevert("transferTokens: invalid token");
IHederaTokenService(HTS_ADDRESS).transferTokens(address(0), to, amounts);
}

function test_HTS_transferTokens_inconsistent_input() public {
// https://hashscan.io/testnet/account/0.0.1421
address owner = 0x4D1c823b5f15bE83FDf5adAF137c2a9e0E78fE15;
address[] memory to = new address[](1);
to[0] = makeAddr("bob");
int64[] memory amounts = new int64[](2);
amounts[0] = 3_000000;
amounts[1] = 1_000000;
vm.prank(owner);
vm.expectRevert("transferTokens: inconsistent input");
IHederaTokenService(HTS_ADDRESS).transferTokens(USDC, to, amounts);
}

function test_HTS_transferTokens_missing_recipients() public {
// https://hashscan.io/testnet/account/0.0.1421
address owner = 0x4D1c823b5f15bE83FDf5adAF137c2a9e0E78fE15;
address[] memory to = new address[](0);
int64[] memory amounts = new int64[](1);
amounts[0] = 3_000000;
vm.prank(owner);
vm.expectRevert("transferTokens: missing recipients");
IHederaTokenService(HTS_ADDRESS).transferTokens(USDC, to, amounts);
}

function test_HTS_transferNFTs_for_allowed_user() external {
uint256[] memory serialId = new uint256[](1);
serialId[0] = 1;
Expand Down

0 comments on commit fd99e8a

Please sign in to comment.