Skip to content

Commit 1481d8e

Browse files
committed
Make associate more lenient
Signed-off-by: Luis Mastrangelo <luis@swirldslabs.com>
1 parent 3d7167a commit 1481d8e

File tree

3 files changed

+16
-24
lines changed

3 files changed

+16
-24
lines changed

contracts/HtsSystemContract.sol

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -584,14 +584,14 @@ contract HtsSystemContract is IHederaTokenService {
584584
if (selector == this.associateToken.selector) {
585585
require(msg.data.length >= 48, "associateToken: Not enough calldata");
586586
address account = address(bytes20(msg.data[40:60]));
587-
bytes32 slot = _isAssociatedSlot(account);
587+
bytes32 slot = _isAssociatedSlot(account, false);
588588
assembly { sstore(slot, true) }
589589
return abi.encode(HederaResponseCodes.SUCCESS);
590590
}
591591
if (selector == this.dissociateToken.selector) {
592592
require(msg.data.length >= 48, "dissociateToken: Not enough calldata");
593593
address account = address(bytes20(msg.data[40:60]));
594-
bytes32 slot = _isAssociatedSlot(account);
594+
bytes32 slot = _isAssociatedSlot(account, false);
595595
assembly { sstore(slot, false) }
596596
return abi.encode(HederaResponseCodes.SUCCESS);
597597
}
@@ -797,17 +797,17 @@ contract HtsSystemContract is IHederaTokenService {
797797

798798
function _redirectForHRC719(bytes4 selector) private returns (bytes memory) {
799799
if (selector == IHRC719.associate.selector) {
800-
bytes32 slot = _isAssociatedSlot(msg.sender);
800+
bytes32 slot = _isAssociatedSlot(msg.sender, false);
801801
assembly { sstore(slot, true) }
802802
return abi.encode(true);
803803
}
804804
if (selector == IHRC719.dissociate.selector) {
805-
bytes32 slot = _isAssociatedSlot(msg.sender);
805+
bytes32 slot = _isAssociatedSlot(msg.sender, false);
806806
assembly { sstore(slot, false) }
807807
return abi.encode(true);
808808
}
809809
if (selector == IHRC719.isAssociated.selector) {
810-
bytes32 slot = _isAssociatedSlot(msg.sender);
810+
bytes32 slot = _isAssociatedSlot(msg.sender, true);
811811
bool res;
812812
assembly { res := sload(slot) }
813813
return abi.encode(res);
@@ -892,11 +892,11 @@ contract HtsSystemContract is IHederaTokenService {
892892
return bytes32(abi.encodePacked(selector, pad, spenderId, ownerId));
893893
}
894894

895-
function _isAssociatedSlot(address account) internal virtual returns (bytes32) {
895+
function _isAssociatedSlot(address account, bool revertIfNotExists) internal virtual returns (bytes32) {
896896
bytes4 selector = IHRC719.isAssociated.selector;
897897
uint192 pad = 0x0;
898898
(uint32 accountId, bool exists) = HtsSystemContract(HTS_ADDRESS).getAccountId(account);
899-
require(exists);
899+
require(!revertIfNotExists || exists, "_isAssociatedSlot: account does not exist");
900900
return bytes32(abi.encodePacked(selector, pad, accountId));
901901
}
902902

contracts/HtsSystemContractJson.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@ contract HtsSystemContractJson is HtsSystemContract {
487487
return slot;
488488
}
489489

490-
function _isAssociatedSlot(address account) internal override returns (bytes32) {
491-
bytes32 slot = super._isAssociatedSlot(account);
490+
function _isAssociatedSlot(address account, bool revertIfNotExists) internal override returns (bytes32) {
491+
bytes32 slot = super._isAssociatedSlot(account, revertIfNotExists);
492492
if (_shouldFetch(slot)) {
493493
bool associated = mirrorNode().isAssociated(address(this), account);
494494
_setValue(slot, bytes32(uint256(associated ? 1 : 0)));

examples/foundry-hts/script/ApproveToken.s.sol

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,24 @@ import {Hsc} from "hedera-forking/Hsc.sol";
77
import {Approver} from "../src/Approver.sol";
88

99
/**
10-
* Usage
11-
*
12-
* forge script ApproveTokenScript --sig "deployApprover()" --rpc-url testnet --broadcast
10+
* Usage
1311
*
14-
* Notice that the `--skip-simulation` is not needed because there is no HTS involved in this step.
15-
*
16-
* forge script ApproveTokenScript --sig "run(address,address)" $TOKEN_ADDR $APPROVER --rpc-url testnet --broadcast --skip-simulation
17-
*
18-
* where $APPROVER is the address returned in the previous step.
12+
* forge script ApproveTokenScript --sig "run(address)" $TOKEN_ADDR --rpc-url testnet --broadcast --skip-simulation --slow
1913
*/
2014
contract ApproveTokenScript is Script {
21-
uint256 private PRIVATE_KEY = vm.envUint("PRIVATE_KEY");
15+
function run(address tokenAddress) external returns (Approver approver, address payable account) {
16+
Hsc.htsSetup();
17+
18+
uint256 PRIVATE_KEY = vm.envUint("PRIVATE_KEY");
2219

23-
function deployApprover() external returns (Approver approver) {
2420
vm.startBroadcast(PRIVATE_KEY);
2521
approver = new Approver();
2622
vm.stopBroadcast();
27-
}
28-
29-
function run(address tokenAddress, address approver) external returns (address payable account) {
30-
Hsc.htsSetup();
3123

3224
vm.startBroadcast(PRIVATE_KEY);
3325
Approver(approver).associate(tokenAddress);
3426

35-
IERC20(tokenAddress).transfer(approver, 50000);
27+
IERC20(tokenAddress).transfer(address(approver), 50000);
3628

3729
VmSafe.Wallet memory wallet = vm.createWallet("wallet");
3830
account = payable(wallet.addr);

0 commit comments

Comments
 (0)