diff --git a/lib/claim.ts b/lib/claim.ts index 267c7ce..9b85e86 100644 --- a/lib/claim.ts +++ b/lib/claim.ts @@ -136,7 +136,7 @@ export async function claimExternal(args: { return manager.waitForTransaction(response.transaction_hash); } -function executeActionOnAccount(functionName: string, accountAddress: string, args: Calldata): Call { +export function executeActionOnAccount(functionName: string, accountAddress: string, args: Calldata): Call { return { contractAddress: accountAddress, entrypoint: "execute_action", diff --git a/src/contracts/escrow_library.cairo b/src/contracts/escrow_library.cairo index 9b1bdd0..e1c9bf5 100644 --- a/src/contracts/escrow_library.cairo +++ b/src/contracts/escrow_library.cairo @@ -91,6 +91,8 @@ mod EscrowLibrary { fn execute_action( ref self: ContractState, this_class_hash: ClassHash, selector: felt252, args: Span ) -> Span { + // This is needed to make sure no arbitrary methods can be called directly using `execute_action` in the escrow account + // Some methods like `claim_internal` should only be called after some checks are performed in the escrow account let is_whitelisted = selector == selector!("claim_external") || selector == selector!("claim_dust") || selector == selector!("cancel"); diff --git a/tests-integration/account.test.ts b/tests-integration/account.test.ts index b507805..564e83a 100644 --- a/tests-integration/account.test.ts +++ b/tests-integration/account.test.ts @@ -1,14 +1,16 @@ +import { CallData } from "starknet"; import { + buildGiftCallData, calculateEscrowAddress, claimInternal, defaultDepositTestSetup, deployer, + executeActionOnAccount, expectRevertWithErrorMessage, getEscrowAccount, randomReceiver, setupGiftProtocol, } from "../lib"; - describe("Escrow Account", function () { it(`Test only protocol can call validate`, async function () { const { factory } = await setupGiftProtocol(); @@ -30,6 +32,16 @@ describe("Escrow Account", function () { ); }); + it(`Test escrow can only do whitelisted lib calls`, async function () { + const { factory } = await setupGiftProtocol(); + const { gift } = await defaultDepositTestSetup({ factory }); + const minimalCallData = CallData.compile([buildGiftCallData(gift)]); + + await expectRevertWithErrorMessage("gift/invalid-selector", () => + deployer.execute(executeActionOnAccount("claim_internal", calculateEscrowAddress(gift), minimalCallData)), + ); + }); + it(`Test escrow contract cant call another contract`, async function () { const { factory } = await setupGiftProtocol(); const { gift, giftPrivateKey } = await defaultDepositTestSetup({ factory });