Skip to content

Commit

Permalink
fix: Add check for parent's existence when checking delegate call (#1…
Browse files Browse the repository at this point in the history
…3013)

Signed-off-by: lukelee-sl <luke.lee@swirldslabs.com>
  • Loading branch information
lukelee-sl committed May 2, 2024
1 parent 890ca1c commit 161bb5d
Show file tree
Hide file tree
Showing 5 changed files with 849 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public HtsCallAddressChecks() {
* @return true if the frame's parent is a delegate call
*/
public boolean hasParentDelegateCall(@NonNull final MessageFrame frame) {
return isDelegateCall(parentOf(frame));
return frame.getMessageFrameStack().size() > 1 && isDelegateCall(parentOf(frame));
}

private MessageFrame parentOf(@NonNull final MessageFrame frame) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.hedera.services.bdd.suites.leaky;

import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT;
import static com.hedera.services.bdd.spec.HapiPropertySource.asContractIdWithEvmAddress;
import static com.hedera.services.bdd.spec.HapiSpec.propertyPreservingHapiSpec;
import static com.hedera.services.bdd.spec.assertions.TransactionRecordAsserts.recordWith;
import static com.hedera.services.bdd.spec.keys.KeyFactory.KeyType.THRESHOLD;
Expand All @@ -25,21 +26,37 @@
import static com.hedera.services.bdd.spec.transactions.TxnVerbs.cryptoCreate;
import static com.hedera.services.bdd.spec.transactions.TxnVerbs.cryptoTransfer;
import static com.hedera.services.bdd.spec.transactions.TxnVerbs.ethereumCall;
import static com.hedera.services.bdd.spec.transactions.TxnVerbs.ethereumCallWithFunctionAbi;
import static com.hedera.services.bdd.spec.transactions.TxnVerbs.tokenAssociate;
import static com.hedera.services.bdd.spec.transactions.TxnVerbs.tokenCreate;
import static com.hedera.services.bdd.spec.transactions.TxnVerbs.uploadInitCode;
import static com.hedera.services.bdd.spec.transactions.contract.HapiParserUtil.asHeadlongAddress;
import static com.hedera.services.bdd.spec.transactions.crypto.HapiCryptoTransfer.tinyBarsFromAccountToAlias;
import static com.hedera.services.bdd.spec.transactions.token.TokenMovement.moving;
import static com.hedera.services.bdd.spec.utilops.CustomSpecAssert.allRunFor;
import static com.hedera.services.bdd.spec.utilops.UtilVerbs.newKeyNamed;
import static com.hedera.services.bdd.spec.utilops.UtilVerbs.overriding;
import static com.hedera.services.bdd.spec.utilops.UtilVerbs.resetToDefault;
import static com.hedera.services.bdd.spec.utilops.UtilVerbs.withOpContext;
import static com.hedera.services.bdd.spec.utilops.records.SnapshotMatchMode.NONDETERMINISTIC_CONTRACT_CALL_RESULTS;
import static com.hedera.services.bdd.spec.utilops.records.SnapshotMatchMode.NONDETERMINISTIC_ETHEREUM_DATA;
import static com.hedera.services.bdd.suites.contract.Utils.FunctionType.FUNCTION;
import static com.hedera.services.bdd.suites.contract.Utils.asAddress;
import static com.hedera.services.bdd.suites.contract.Utils.getABIFor;
import static com.hedera.services.bdd.suites.crypto.CryptoCreateSuite.ACCOUNT;
import static com.hedera.services.bdd.suites.leaky.LeakyContractTestsSuite.RECEIVER;
import static com.hedera.services.bdd.suites.token.TokenAssociationSpecs.VANILLA_TOKEN;
import static com.hedera.services.bdd.suites.token.TokenTransactSpecs.SUPPLY_KEY;
import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.SUCCESS;
import static com.hederahashgraph.api.proto.java.TokenType.FUNGIBLE_COMMON;
import static com.swirlds.common.utility.CommonUtils.unhex;

import com.google.protobuf.ByteString;
import com.hedera.node.app.hapi.utils.ethereum.EthTxData.EthTransactionType;
import com.hedera.services.bdd.junit.HapiTest;
import com.hedera.services.bdd.junit.HapiTestSuite;
import com.hedera.services.bdd.spec.HapiSpec;
import com.hedera.services.bdd.spec.transactions.contract.HapiParserUtil;
import com.hedera.services.bdd.suites.HapiSuite;
import com.hederahashgraph.api.proto.java.ResponseCodeEnum;
import java.math.BigInteger;
Expand All @@ -57,6 +74,11 @@ public class LeakyEthereumTestsSuite extends HapiSuite {
private static final String PAY_RECEIVABLE_CONTRACT = "PayReceivable";
private static final Logger log = LogManager.getLogger(LeakyEthereumTestsSuite.class);

private static final String EVM_VERSION_PROPERTY = "contracts.evm.version";
private static final String ALLOW_CALLS_TO_NON_CONTRACT_ACCOUNTS = "contracts.evm.allowCallsToNonContractAccounts";
private static final String DYNAMIC_EVM_PROPERTY = "contracts.evm.version.dynamic";
private static final String EVM_VERSION_050 = "v0.50";

public static void main(String... args) {
new LeakyEthereumTestsSuite().runSuiteAsync();
}
Expand All @@ -68,7 +90,7 @@ public boolean canRunConcurrent() {

@Override
public List<HapiSpec> getSpecsInSuite() {
return Stream.of(legacyUnprotectedEtxBeforeEIP155(), legacyEtxAfterEIP155())
return Stream.of(legacyUnprotectedEtxBeforeEIP155(), legacyEtxAfterEIP155(), callHtsSystemContractTest())
.toList();
}

Expand Down Expand Up @@ -166,6 +188,64 @@ HapiSpec legacyEtxAfterEIP155() {
resetToDefault(CHAIN_ID_PROP));
}

@HapiTest
final HapiSpec callHtsSystemContractTest() {
final var callHtsSystemContractTxn = "callHtsSystemContractTxn";
final var function = getABIFor(FUNCTION, "transferToken", "IHederaTokenService");
final var HTS_SYSTEM_CONTRACT = "hts";
final var HTS_SYSTEM_CONTRACT_ADDRESS = "0000000000000000000000000000000000000167";

return propertyPreservingHapiSpec("callHtsSystemContractTest")
.preserving(EVM_VERSION_PROPERTY, DYNAMIC_EVM_PROPERTY)
.given(
overriding(DYNAMIC_EVM_PROPERTY, "true"),
overriding(EVM_VERSION_PROPERTY, EVM_VERSION_050),
overriding(ALLOW_CALLS_TO_NON_CONTRACT_ACCOUNTS, "true"),
newKeyNamed(SECP_256K1_SOURCE_KEY).shape(SECP_256K1_SHAPE),
newKeyNamed(SUPPLY_KEY),
cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, SECP_256K1_SOURCE_KEY, ONE_HUNDRED_HBARS)),
cryptoCreate(RELAYER).balance(6 * ONE_MILLION_HBARS),
cryptoCreate(ACCOUNT).balance(6 * ONE_MILLION_HBARS),
cryptoCreate(TOKEN_TREASURY),
cryptoCreate(RECEIVER),
tokenCreate(VANILLA_TOKEN)
.tokenType(FUNGIBLE_COMMON)
.treasury(TOKEN_TREASURY)
.supplyKey(SUPPLY_KEY)
.initialSupply(1_000),
tokenAssociate(ACCOUNT, VANILLA_TOKEN),
tokenAssociate(RECEIVER, VANILLA_TOKEN),
cryptoTransfer(moving(500, VANILLA_TOKEN).between(TOKEN_TREASURY, ACCOUNT)))
.when(withOpContext((spec, opLog) -> {
final var receiver1 =
asHeadlongAddress(asAddress(spec.registry().getAccountID(RECEIVER)));
final var sender =
asHeadlongAddress(asAddress(spec.registry().getAccountID(ACCOUNT)));

spec.registry()
.saveContractId(
HTS_SYSTEM_CONTRACT,
asContractIdWithEvmAddress(
ByteString.copyFrom(unhex(HTS_SYSTEM_CONTRACT_ADDRESS))));
allRunFor(
spec,
ethereumCallWithFunctionAbi(
false,
HTS_SYSTEM_CONTRACT,
function,
HapiParserUtil.asHeadlongAddress(
asAddress(spec.registry().getTokenID(VANILLA_TOKEN))),
sender,
receiver1,
1L)
.payingWith(RELAYER)
.type(EthTransactionType.EIP1559)
.via(callHtsSystemContractTxn)
.hasKnownStatus(SUCCESS));
}))
.then();
}

@Override
protected Logger getResultsLogger() {
return log;
Expand Down

Large diffs are not rendered by default.

0 comments on commit 161bb5d

Please sign in to comment.